The static keyword can be used in 4 scenarios
- static variables
- static methods
- static blocks of code
- static nested class
Let's look at static variables and static methods first.
Static variable
- It is a variable which belongs to the class and not to object (instance).
- Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
- A single copy to be shared by all instances of the class.
- A static variable can be accessed directly by the class name and doesn’t need any object.
- Syntax:
Class.variable
Static method
- It is a method which belongs to the class and not to the object (instance).
- A static method can access only static data. It can not access non-static data (instance variables) unless it has/creates an instance of the class.
- A static method can call only other static methods and can not call a non-static method from it unless it has/creates an instance of the class.
- A static method can be accessed directly by the class name and doesn’t need any object.
- Syntax:
Class.methodName() - A static method cannot refer to
thisorsuperkeywords in anyway.
Static class
Java also has "static nested classes". A static nested class is just one which doesn't implicitly have a reference to an instance of the outer class.
Static nested classes can have instance methods and static methods.
There's no such thing as a top-level static class in Java.
Side note:
main method is
staticsince it must be be accessible for an application to run before any instantiation takes place.
final keyword is used in several different contexts to define an entity which cannot later be changed.
A
finalclass cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes arefinal, for examplejava.lang.Systemandjava.lang.String. All methods in afinalclass are implicitlyfinal.A
finalmethod can't be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.A
finalvariable can only be initialized once, either via an initializer or an assignment statement.
It does not need to be initialized at the point of declaration, this is called ablank finalvariable, but in this case:- A
blank finalinstance variable must be assigned at every constructor of its class. - A
blank finalstatic variable must be assigned in a static initializer in its class.
- A
Note: If the variable is a reference, this means that the variable cannot be re-bound to reference another object. But the object that it references is still mutable, if it was originally mutable.
When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. Once it has been assigned, the value of the final variable cannot change.
Videos
The static keyword can be used in 4 scenarios
- static variables
- static methods
- static blocks of code
- static nested class
Let's look at static variables and static methods first.
Static variable
- It is a variable which belongs to the class and not to object (instance).
- Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
- A single copy to be shared by all instances of the class.
- A static variable can be accessed directly by the class name and doesn’t need any object.
- Syntax:
Class.variable
Static method
- It is a method which belongs to the class and not to the object (instance).
- A static method can access only static data. It can not access non-static data (instance variables) unless it has/creates an instance of the class.
- A static method can call only other static methods and can not call a non-static method from it unless it has/creates an instance of the class.
- A static method can be accessed directly by the class name and doesn’t need any object.
- Syntax:
Class.methodName() - A static method cannot refer to
thisorsuperkeywords in anyway.
Static class
Java also has "static nested classes". A static nested class is just one which doesn't implicitly have a reference to an instance of the outer class.
Static nested classes can have instance methods and static methods.
There's no such thing as a top-level static class in Java.
Side note:
main method is
staticsince it must be be accessible for an application to run before any instantiation takes place.
final keyword is used in several different contexts to define an entity which cannot later be changed.
A
finalclass cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes arefinal, for examplejava.lang.Systemandjava.lang.String. All methods in afinalclass are implicitlyfinal.A
finalmethod can't be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.A
finalvariable can only be initialized once, either via an initializer or an assignment statement.
It does not need to be initialized at the point of declaration, this is called ablank finalvariable, but in this case:- A
blank finalinstance variable must be assigned at every constructor of its class. - A
blank finalstatic variable must be assigned in a static initializer in its class.
- A
Note: If the variable is a reference, this means that the variable cannot be re-bound to reference another object. But the object that it references is still mutable, if it was originally mutable.
When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. Once it has been assigned, the value of the final variable cannot change.
static means it belongs to the class not an instance, this means that there is only one copy of that variable/method shared between all instances of a particular Class.
public class MyClass {
public static int myVariable = 0;
}
//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
MyClass.myVariable = 5; //This change is reflected in both instances
final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
note A note on final methods and final classes, this is a way of explicitly stating that the method or class can not be overridden / extended respectively.
Extra Reading So on the topic of static, we were talking about the other uses it may have, it is sometimes used in static blocks. When using static variables it is sometimes necessary to set these variables up before using the class, but unfortunately you do not get a constructor. This is where the static keyword comes in.
public class MyClass {
public static List<String> cars = new ArrayList<String>();
static {
cars.add("Ferrari");
cars.add("Scoda");
}
}
public class TestClass {
public static void main(String args[]) {
System.out.println(MyClass.cars.get(0)); //This will print Ferrari
}
}
You must not get this confused with instance initializer blocks which are called before the constructor per instance.
This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.
Now a days interviewers are asking another favorite question what is effectively final from java 1.8.
I will explain in the end about this effectively final in java 1.8.
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo; // comment-1
public Test() {
foo = new ArrayList(); // comment-2
foo.add("foo"); // Modification-1 comment-3
}
public void setFoo(List foo) {
//this.foo = foo; Results in compile time error.
}
}
In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.
About constructor: Constructor can be invoked only one time per object creation by using the new keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.
About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.
Scenario 1
private final List foo; // 1
foo is an instance variable. When we create Test class object then the instance variable foo, will be copied inside the object of Test class. If we assign final foo inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.
If we assign final foo inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for a final variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.
Scenario 2
private static final List foo = new ArrayList();
foo is now a static variable. When we create an instance of Test class, foo will not be copied to the object because foo is static. Now foo is not an independent property of each object. This is a property of Test class. But foo can be seen by multiple objects and if every object of Test which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value of final static variable at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.). To stop this, compiler knows final static cannot be initialized inside constructor and also cannot provide method to assign object to it. So we have to declare and define final List object at the same place at comment-1 in above program.
Scenario 3
t.foo.add("bar"); // Modification-2
Above Modification-2 is from your question. In the above case, you are not changing the first referenced object, but you are adding content inside foo which is allowed. Compiler complains if you try to assign a new ArrayList() to the foo reference variable.
Rule If you have initialized a final variable, then you cannot change it to refer to a different object. (In this case ArrayList)
final classes cannot be subclassed
final methods cannot be overridden. (This method is in superclass)
final methods can override. (Read this in grammatical way. This method is in a subclass)
Now let's see what is effectively final in java 1.8?
public class EffectivelyFinalDemo { //compile code with java 1.8
public void process() {
int thisValueIsFinalWithoutFinalKeyword = 10; //variable is effectively final
//to work without final keyword you should not reassign value to above variable like given below
thisValueIsFinalWithoutFinalKeyword = getNewValue(); // delete this line when I tell you.
class MethodLocalClass {
public void innerMethod() {
//below line is now showing compiler error like give below
//Local variable thisValueIsFinalWithoutFinalKeyword defined in an enclosing scope must be final or effectively final
System.out.println(thisValueIsFinalWithoutFinalKeyword); //on this line only final variables are allowed because this is method local class
// if you want to test effectively final is working without final keyword then delete line which I told you to delete in above program.
}
}
}
private int getNewValue() {
return 0;
}
}
Above program will throw error in java 1.7 or <1.8 if you do not use final keyword. Effectively final is a part of Method Local Inner classes. I know you would rarely use such effectively final in method local classes, but for interview we have to be prepared.
You are always allowed to initialize a final variable. The compiler makes sure that you can do it only once.
Note that calling methods on an object stored in a final variable has nothing to do with the semantics of final. In other words: final is only about the reference itself, and not about the contents of the referenced object.
Java has no concept of object immutability; this is achieved by carefully designing the object, and is a far-from-trivial endeavor.
Please correct me if I am wrong, and explain where my understanding is incomplete.
From what I've read both static and final are keywords. If you make a variable or method static, it would only be accessed by the class itself and not by an instance of the class (object). A static class would be useful if it was nested inside another class and you didn't want an instance of the outer class to access the inner class.
If you make a variable final, then it is initialized once and not changed. A final class can't be subclassed, and a final method can't be overwritten. If a variable is static final, then it cannot be changed and it can only be accessed by the class itself and not an object of the class.
People use static all the time, but why is it useful to limit the access of a method or variable to the class itself and not any instances of it?