Housekeeping There are two items on the horizon.
Easy.java
is due Wednesday. It'e easy so get it knocked off. When most are in, I will start grading.- There is a quiz on
j1.pdf
on Wednesday. The quiz is open 5 min prior to the start of class. It should not take you very long at all if you have done the reading.
static
and final
Today, you will learn about these keywords.
final
means, "Can't be re-assigned."
This is a property of variables. Consider this program
/************************************************** * Author: Morrison * Date created: 31 Aug 2020 * Date last modified: 31 Aug 2020 **************************************************/ import java.util.ArrayList; public class Finality { public Finality() { } public static void main(String[] args) { final int x = 5; //x++; System.out.println(x); final ArrayList<String> al = new ArrayList<String>(); al.add("hello"); System.out.println(al); } }
If you uncomment the line with x++;
, the compiler will
hand you an error message. Variables marked final
cannot be
re-assigned. However, whatever is being stored under a final
variable has no idea about finality.
The ArrayList we create is pointed at by a final
varialble. This
means the variable can't be reassigned. However, the state of this mutable list
can be changed.
Constness This means a that an object cannot changed in any way via a variable.
- >
- final + primitive type gives constness. This is because primitives have no methods, much less any that can change state.
- final + immutible gives constness, because the state of the object can't be changed
What does a variable store? If it iss primitive, it stores its value. If it is of object type, the variable stores a heap memory address.
static
Cling
We will put some static elements in our Point
class. We will
also learn about some static service classes that are class-strated in
the sense that you never make an instance of them.
Here is the picture of instance world and static world in a class.
-|g This side of the world -|r has a ladder. It can -|e reach over to the -|a other side -|s -|e -| -| -|g -|r non-static (instance) -|e methods -|a static methods, including main() -|s state variables -|e static variables -| instance world -| static world --------------------------------------------------
Because of the greased wall, static items do not have direct access to instance items.
/************************************************** * Author: Morrison * Date created: 31 Aug 2020 * Date last modified: 31 Aug 2020 **************************************************/ public class Naughty { private int x; public Naughty() { x = 42; } public static void main(String[] args) { //Illegal; attempt to climb greased wall //System.out.println(x); //legal: works via an instance of the class Naughy n = new Naughy(); System.out.println(n.x); } }
Uncomment the illegal line. See the ugly error message. Then re-comment it and run the program again (successfully).
Let's give our Point class a static constant ORIGIN
.
Notice the poopsmith, which is a private helper method.
public class Point { public static Point ORIGIN; // initalize your static data members here //this is called a "static block." static { ORIGIN = new Point(); } //state or instance variable final private int x; final private int y; //signature: list of types in the argment list public Point(int x, int y) { this.x = x; this.y = y; } //method name overloading. Two methods can have //the same name if their sigs are different. public Point() { this(0,0); } @Override public String toString() { return String.format("(%s, %s)", x, y); } @Override public boolean equals(Object o) { //the species test if( !(o instanceof Point)) { return false; } Point that = (Point) o; return that.x == x && that.y == y; } public int getX() { return x; } public int getY() { return y; } public double distanceTo(Point that) { return Math.hypot(x - that.x, y - that.y); } public int taxiCabDistance(Point that) { return abs(x - that.x) + abs(y - that.y); } //poopsmith private int abs(int x) { // ternary operator: P? ifTrue: ifFalse // predicate: boolean valued expression. // P is one of these return x < 0? -x : x; } public static void main(String[] args) { Point p = new Point(3,4); Point origin = new Point(); Point q = new Point(3,4); System.out.println(p); System.out.println(origin); System.out.println(origin.distanceTo(p)); System.out.println(p.distanceTo(origin)); System.out.println(origin.taxiCabDistance(p)); System.out.println(p.taxiCabDistance(origin)); System.out.println(p == q); System.out.println(p.equals(q)); System.out.println(Point.ORIGIN); } }
Finally, an interesting use of static to give serial numbers to objects
/************************************************** * Author: Morrison * Date created: 31 Aug 2020 * Date last modified: 31 Aug 2020 **************************************************/ public class Minter { private static int idWell; static { idWell = 1; } private final int ID; public Minter() { ID = idWell; idWell++; } public static int nextID() { return idWell; } @Override public String toString() { return String.format("Minter(%s)", ID); } public static void main(String[] args) { for(int k = 0; k > 10; k++) { System.out.println(new Minter()); } //Minter q = new Minter(); System.out.println(Minter.nextID()); } }
Run it and see this.
unix> java Minter Minter(1) Minter(2) Minter(3) Minter(4) Minter(5) Minter(6) Minter(7) Minter(8) Minter(9) Minter(10) 11 unix>