static keyword.
class Test1 {
int var1 = 1; // instance fields (unique to each instance)
static int var2 = 1; // class fields
public Test1() {
Integer localVar1;
// Access fields
localVar1 = var1; // OK
localVar1 = var2; // OK
// Access fields using an instance reference
localVar1 = (new Test1()).var1; // OK
localVar1 = (new Test1()).var2; // OK - Warning: The static field Test1.var2 should be accessed in a static way
// Access fields using the class name
localVar1 = Test1.var1; // compiler error: Cannot make a static reference to the non-static field Test1.var1
localVar1 = Test1.var2; // OK
}
public void doSomething() {
Integer localVar1;
// Access fields
localVar1 = var1; // OK
localVar1 = var2; // OK
// Access fields using an instance reference
localVar1 = (new Test1()).var1; // OK
localVar1 = (new Test1()).var2; // OK - Warning: The static field Test1.var2 should be accessed in a static way
// Access fields using the class name
localVar1 = Test1.var1; // compiler error: Cannot make a static reference to the non-static field Test1.var1
localVar1 = Test1.var2; // OK
}
public static void doSomethingElse() {
Integer localVar1;
// Access fields
localVar1 = var1; // compiler error: Cannot make a static reference to the non-static field var1
localVar1 = var2; // OK
// Access fields using an instance reference
localVar1 = (new Test1()).var1; // OK
localVar1 = (new Test1()).var2; // OK - Warning: The static field Test1.var2 should be accessed in a static way
// Access fields using the class name
localVar1 = Test1.var1; // compiler error: Cannot make a static reference to the non-static field Test1.var1
localVar1 = Test1.var2; // OK
}
}
public: Accessible from anywhere.private: Accessible only within the same class.protected: Accessible within the same package and by subclasses.final fields cannot be reassigned after initialization.
class Test2 {
// Final field initialized at declaration
final int CONSTANT = 1;
// Final field to be initialized in constructor
final int var1;
// Static final field (compile-time constant)
static final int var2 = 1;
// Final object reference (object can be modified, reference cannot)
final List<String> list1 = new ArrayList<>();
// Compiler error if var1 not initialized: The blank final field var3 may not have been initialized
public Test2() {
this.var1 = 1; // must initialize final field in constructor
}
public void doSomething() {
CONSTANT = 200; // Compiler error: The final field Test2.CONSTANT cannot be assigned
var1 = 1; // Compiler error: The final field Test2.var1 cannot be assigned
list1 = new ArrayList<>(); // Compiler error: The final field Test2.list1 cannot be assigned
// can modify the object that final reference points to
list1.add("Item 1"); // OK
list1.add("Item 2"); // OK
}
}
this keyword to access instance fields when shadowed.
class Test3 {
int var1 = 1;
static int var2 = 1;
public void doSomething() {
int var1 = 2; // local variable shadows the instance field
System.out.println(var1); // prints local variable var1 (2)
System.out.println(new Test3().var1); // prints instance field var1 (1)
int var2 = 2; // local variable shadows the static field
System.out.println(var2); // prints local variable var2 (2)
System.out.println(Test3.var2); // prints static field var2 (1)
}
}
class Test4 extends Test3 {
int var1 = 10; // shadows parent field
static int var2 = 10; // shadows parent field
public void doSomethingElse() {
System.out.println(var1); // prints child instance field var1 (10)
System.out.println(super.var1); // prints parent instance field var1 (1)
System.out.println(var2); // prints child static field var2 (10)
System.out.println(super.var2); // prints parent static field var2 (1)
}
}