Setting a static final variable in constructor - java

what i basicly want is this:
public class Test
{
private static final Integer a;
public Test(Integer a)
{
this.a = a;
}
}
This obviously doesn't work, cause the 2nd created instance would try to override the final variable.
So is there a way to give all the instances the same immutable value via the constructor?

Static final values should be initialized in a static context, not by instances.
One options is to set the value in the declaration:
private static final Integer a=FileConfig.getInstance().getA();
Each class can have a static {} block where code is called to initialize the static parts of the class.
static {
a = FileConfig.getInstance().getA();
}
Finally, you can set the value from a static method
private static int getA() {
return FileConfig.getInstance().getA();
}
private static final Integer a=getA();
In closure, static instance initialization does not belong in instance constructors.
If the configuration values change sometimes, there is simply no reason to store the value a in a static final variable. If you want to create each instance with the constant a in the constructor, what is the purpose of a static field in the first place? Somehow, when you call the constructor for the first time, you are passing in a value from somewhere. If the value deserves to be static and final, you can acquire it from within the static initializer. If the configuration is not a singleton, but every instance always produces the same value of a, you could easily do a = new FileConfig().getA();.
Other than that, you could make the value non-final, and rest assured that since you always put in the same value of a, the static variable will not change.
Still, you could make a a final instance variable of the class, set in the constructor.

So is there a way to give all the instances the same immutable value via the constructor?
I assume you want a value to be assigned to a the first time an object of type Test is created but not when any subsequent instance is created. In that case you cannot declare it final. a will be null initially, the constructor has to check if it is null and assign it a value in that case.
But I urge you to look at the design, especially why the caller have to provide the value. Isn't it counter-intuitive that after the second Test object is created Test.a does not change in the following case?
// assume this is the first `Test` object created:
Test t = new Test(5); // Test.a is 5
Test t = new Test(6); // Test.a is *still* 5

Related

Assign a static variable before declaring

I'm learning Java and write the simple code below:
public class Test {
private int a = b;
private final static int b = 10;
public int getA() {
return a;
}
}
public class Hello {
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.getA());
}
}
The result: 10. Well done! It run successfully and have no error.
Can anyone please explain why I can assign a static variable before declaring it?
The assignment
private int a = b;
takes place when you create a new instance of Test (just before the constructor is called).
The declaration and initialization of the static variable b, takes place before the instance is created, when the class is loaded.
The order of the statements doesn't matter, since static variables are always initialized first.
Javavariables are initialised this order:
Static variables of the superclasses if any
static variables of the current class.
Static variables, and static blocks in the order that they are
declared
Instance variables of the superclasses
All instance variables of the current class.
Instance variables, and instance level initialisation blocks, in
declaration order
Therefore "b" is intialized before the "a".
Hope this helps.
Static variables are bound to a class - which of course always exists before instances of the class. Thus, you can freely assign it to instance fields.
The order of declaring variables doesn't really matter in your code as in reality the static variable is going to be initialized before non-static ones.
The code you wrote works well because
private final static int b = 10;
is a class variable (static field). Those type of variables are initialised for first.
Then is executed the line
private int a = b;
which initialise the instance variable (field) a.
In short, it doesn't matter the order in which those variables are declared in your code. Class variables are always declared before instance variables.

Why does this method call return the same reference every time it’s called?

public class SomeClass {
private static final SomeClass INSTANCE = new SomeClass();
private SomeClass() {}
public static SomeClass getInstance() {return INSTANCE;}
public static void main(String[] args) {
System.out.println(getInstance());
}
}
Why does the getInstance method always return the same reference every time?
The reason is that the field INSTANCE is both static and final.
static means its scope is bound to the enclosing class, and not any single instance of that class. (Even though you're not creating any instances of it anyway.) In a running Java program, there's only one of each class, even though a class may have many instances.
final means that the value of this field cannot be changed after it's initialised.
Because it's static, there's only one "slot" for the object, and because it's final the contents of this slot will never change, which is why returning those contents will always return the same thing.
You're assigning a reference to a constant (INSTANCE), and your getInstance method returns that constant, so yes, it always returns the same reference.
The reason is because you have declared the instance
private static final SomeClass INSTANCE = new SomeClass();
as final and static , so the instance will be allocated a single memory and that also be constant, therefore it is using singleton pattern
Take a look at this stuff -
Implementation of Singleton Pattern Class in Java Introduction
Yes it will return the same reference always as long as the class is loaded. Its static final
INSTANTA is declared final, which means its value cannot be changed once it has been initialized. Hence, program guarantees that getInstanta returns same instance always.
You declared both method and constant static. This means it is a member of the class instead of an object created from that class. As the class only exists once it will always return the same object. Furthermore since your variable is final it can never be assigned to a new object.

How does the "final" keyword in Java work? (I can still modify an object.)

In Java we use final keyword with variables to specify its values are not to be changed.
But I see that you can change the value in the constructor / methods of the class. Again, if the variable is static then it is a compilation error.
Here is the code:
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test()
{
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
}
Above code works fine and no errors.
Now change the variable as static:
private static final List foo;
Now it is a compilation error. How does this final really work?
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;
public Test() {
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
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 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 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 which is created by using the new keyword which will ultimately invoke the Test constructor which changes the value at the time of multiple object creation (Remember static foo is not copied in every object, but is shared between multiple objects.)
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.
Final keyword has a numerous way to use:
A final class cannot be subclassed.
A final method cannot be overridden by subclasses
A final variable can only be initialized once
Other usage:
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
A static class variable will exist from the start of the JVM, and should be initialized in the class. The error message won't appear if you do this.
The final keyword can be interpreted in two different ways depending on what it's used on:
Value types: For ints, doubles etc, it will ensure that the value cannot change,
Reference types: For references to objects, final ensures that the reference will never change, meaning that it will always refer to the same object. It makes no guarantees whatsoever about the values inside the object being referred to staying the same.
As such, final List<Whatever> foo; ensures that foo always refers to the same list, but the contents of said list may change over time.
If you make foo static, you must initialize it in the class constructor (or inline where you define it) like the following examples.
Class constructor (not instance):
private static final List foo;
static
{
foo = new ArrayList();
}
Inline:
private static final List foo = new ArrayList();
The problem here is not how the final modifier works, but rather how the static modifier works.
The final modifier enforces an initialization of your reference by the time the call to your constructor completes (i.e. you must initialize it in the constructor).
When you initialize an attribute in-line, it gets initialized before the code you have defined for the constructor is run, so you get the following outcomes:
if foo is static, foo = new ArrayList() will be executed before the static{} constructor you have defined for your class is executed
if foo is not static, foo = new ArrayList() will be executed before your constructor is run
When you do not initilize an attribute in-line, the final modifier enforces that you initialize it and that you must do so in the constructor. If you also have a static modifier, the constructor you will have to initialize the attribute in is the class' initialization block : static{}.
The error you get in your code is from the fact that static{} is run when the class is loaded, before the time you instantiate an object of that class. Thus, you will have not initialized foo when the class is created.
Think of the static{} block as a constructor for an object of type Class. This is where you must do the initialization of your static final class attributes (if not done inline).
Side note:
The final modifier assures const-ness only for primitive types and references.
When you declare a final object, what you get is a final reference to that object, but the object itself is not constant.
What you are really achieving when declaring a final attribute is that, once you declare an object for your specific purpose (like the final List that you have declared), that and only that object will be used for that purpose: you will not be able to change List foo to another List, but you can still alter your List by adding/removing items (the List you are using will be the same, only with its contents altered).
This is a very good interview question. Sometimes they might even ask you what is the difference between a final object and immutable object.
1) When someone mentions a final object, it means that the reference cannot be changed, but its state(instance variables) can be changed.
2) An immutable object is one whose state can not be changed, but its reference can be changed.
Ex:
String x = new String("abc");
x = "BCG";
ref variable x can be changed to point a different string, but value of "abc" cannot be changed.
3) Instance variables(non static fields) are initialized when a constructor is called. So you can initialize values to you variables inside a constructor.
4) "But i see that you can change the value in the constructor/methods of the class". -- You cannot change it inside a method.
5) A static variable is initialized during class loading. So you cannot initialize inside a constructor, it has to be done even before it. So you need to assign values to a static variable during declaration itself.
The final keyword in java is used to restrict the user. The java final keyword can be used in many context. Final can be:
variable
method
class
The final keyword can be applied with the variables, a final variable that has no value, is called blank final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final variable can be static also which will be initialized in the static block only.
Java final variable:
If you make any variable as final, you cannot change the value of final variable(It will be constant).
Example of final variable
There is a final variable speedlimit, we are going to change the value of this variable, but It can't be changed because final variable once assigned a value can never be changed.
class Bike9{
final int speedlimit=90;//final variable
void run(){
speedlimit=400; // this will make error
}
public static void main(String args[]){
Bike9 obj=new Bike9();
obj.run();
}
}//end of class
Java final class:
If you make any class as final, you cannot extend it.
Example of final class
final class Bike{}
class Honda1 extends Bike{ //cannot inherit from final Bike,this will make error
void run(){
System.out.println("running safely with 100kmph");
}
public static void main(String args[]){
Honda1 honda= new Honda();
honda.run();
}
}
Java final method:
If you make any method as final, you cannot override it.
Example of final method
(run() in Honda cannot override run() in Bike)
class Bike{
final void run(){System.out.println("running");}
}
class Honda extends Bike{
void run(){System.out.println("running safely with 100kmph");}
public static void main(String args[]){
Honda honda= new Honda();
honda.run();
}
}
shared from:
http://www.javatpoint.com/final-keyword
Worth to mention some straightforward definitions:
Classes/Methods
You can declare some or all of a class methods as final, in order to indicate that the method cannot be overridden by subclasses.
Variables
Once a final variable has been initialized, it always contains the same value.
final basically avoid overwrite/superscribe by anything (subclasses, variable "reassign"), depending on the case.
"A final variable can only be assigned once"
*Reflection* - "wowo wait, hold my beer".
Freeze of final fields happen in two scenarios:
End of constructor.
When reflection sets the field's value. (as many times as it wants to)
Let's break the law
public class HoldMyBeer
{
final int notSoFinal;
public HoldMyBeer()
{
notSoFinal = 1;
}
static void holdIt(HoldMyBeer beer, int yetAnotherFinalValue) throws Exception
{
Class<HoldMyBeer> cl = HoldMyBeer.class;
Field field = cl.getDeclaredField("notSoFinal");
field.setAccessible(true);
field.set(beer, yetAnotherFinalValue);
}
public static void main(String[] args) throws Exception
{
HoldMyBeer beer = new HoldMyBeer();
System.out.println(beer.notSoFinal);
holdIt(beer, 50);
System.out.println(beer.notSoFinal);
holdIt(beer, 100);
System.out.println(beer.notSoFinal);
holdIt(beer, 666);
System.out.println(beer.notSoFinal);
holdIt(beer, 8888);
System.out.println(beer.notSoFinal);
}
}
Output:
1
50
100
666
8888
The "final" field has been assigned 5 different "final" values (note the quotes). And it could keep being assigned different values over and over...
Why? Because reflection is like Chuck Norris, and if it wants to change the value of an initialized final field, it does. Some say he himself is the one that pushes the new values into the stack :
Code:
7: astore_1
11: aload_1
12: getfield
18: aload_1
19: bipush 50 //wait what
27: aload_1
28: getfield
34: aload_1
35: bipush 100 //come on...
43: aload_1
44: getfield
50: aload_1
51: sipush 666 //...you were supposed to be final...
60: aload_1
61: getfield
67: aload_1
68: sipush 8888 //ok i'm out whatever dude
77: aload_1
78: getfield
final is a reserved keyword in Java to restrict the user and it can be applied to member variables, methods, class and local variables. Final variables are often declared with the static keyword in Java and are treated as constants. For example:
public static final String hello = "Hello";
When we use the final keyword with a variable declaration, the value stored inside that variable cannot be changed latter.
For example:
public class ClassDemo {
private final int var1 = 3;
public ClassDemo() {
...
}
}
Note: A class declared as final cannot be extended or inherited (i.e, there cannot be a subclass of the super class). It is also good to note that methods declared as final cannot be overridden by subclasses.
Benefits of using the final keyword are addressed in this thread.
First of all, the place in your code where you are initializing (i.e. assigning for the first time) foo is here:
foo = new ArrayList();
foo is an object (with type List) so it is a reference type, not a value type (like int). As such, it holds a reference to a memory location (e.g. 0xA7D2A834) where your List elements are stored. Lines like this
foo.add("foo"); // Modification-1
do not change the value of foo (which, again, is just a reference to a memory location). Instead, they just add elements into that referenced memory location. To violate the final keyword, you would have to try to re-assign foo as follows again:
foo = new ArrayList();
That would give you a compilation error.
Now, with that out of the way, think about what happens when you add the static keyword.
When you do NOT have the static keyword, each object that instantiates the class has its own copy of foo. Therefore, the constructor assigns a value to a blank, fresh copy of the foo variable, which is perfectly fine.
However, when you DO have the static keyword, only one foo exists in memory that is associated with the class. If you were to create two or more objects, the constructor would be attempting to re-assign that one foo each time, violating the final keyword.
Suppose you have two moneyboxes, red and white. You assign these moneyboxes only two children and they are not allowed interchange their boxes. So You have red or white moneyboxes(final) you cannot modify the box but you can put money on your box.Nobody cares (Modification-2).
Read all the answers.
There is another user case where final keyword can be used i.e. in a method argument:
public void showCaseFinalArgumentVariable(final int someFinalInt){
someFinalInt = 9; // won't compile as the argument is final
}
Can be used for variable which should not be changed.
When you make it static final it should be initialized in a static initialization block
private static final List foo;
static {
foo = new ArrayList();
}
public Test()
{
// foo = new ArrayList();
foo.add("foo"); // Modification-1
}
The final keyword indicates that a variable may only be initialized once. In your code you are only performing one initialization of final so the terms are satisfied. This statement performs the lone initialization of foo. Note that final != immutable, it only means that the reference cannot change.
foo = new ArrayList();
When you declare foo as static final the variable must be initialized when the class is loaded and cannot rely on instantiation (aka call to constructor) to initialize foo since static fields must be available without an instance of a class. There is no guarantee that the constructor will have been called prior to using the static field.
When you execute your method under the static final scenario the Test class is loaded prior to instantiating t at this time there is no instantiation of foo meaning it has not been initialized so foo is set to the default for all objects which is null. At this point I assume your code throws a NullPointerException when you attempt to add an item to the list.
Since the final variable is non-static, it can be initialized in constructor. But if you make it static it can not be initialized by constructor (because constructors are not static).
Addition to list is not expected to stop by making list final. final just binds the reference to particular object. You are free to change the 'state' of that object, but not the object itself.
Following are different contexts where final is used.
Final variables A final variable can only be assigned once. If the variable is a reference, this means that the variable cannot be re-bound to reference another object.
class Main {
public static void main(String args[]){
final int i = 20;
i = 30; //Compiler Error:cannot assign a value to final variable i twice
}
}
final variable can be assigned value later (not compulsory to assigned a value when declared), but only once.
Final classes A final class cannot be extended (inherited)
final class Base { }
class Derived extends Base { } //Compiler Error:cannot inherit from final Base
public class Main {
public static void main(String args[]) {
}
}
Final methods A final method cannot be overridden by subclasses.
//Error in following program as we are trying to override a final method.
class Base {
public final void show() {
System.out.println("Base::show() called");
}
}
class Derived extends Base {
public void show() { //Compiler Error: show() in Derived cannot override
System.out.println("Derived::show() called");
}
}
public class Main {
public static void main(String[] args) {
Base b = new Derived();;
b.show();
}
}
I thought of writing an updated and in depth answer here.
final keyword can be used in several places.
classes
A final class means that no other class can extend that final class. When Java Run Time (JRE) knows an object reference is in type of a final class (say F), it knows that the value of that reference can only be in type of F.
Ex:
F myF;
myF = new F(); //ok
myF = someOther; //someOther cannot be in type of a child class of F.
//because F cannot be extended.
So when it executes any method of that object, that method doesn't need to be resolved at run time using a virtual table. i.e. run-time polymorphism cannot be applied. So the run time doesn't bother about that. Which means it saves processing time, which will improve performance.
methods
A final method of any class means that any child class extending that class cannot override that final method(s). So the run time behavior in this scenario is also quite same with the previous behavior I mentioned for classes.
fields, local variables, method parameters
If one specified any kind of above as final, it means that the value is already finalized, so the value cannot be changed.
Ex:
For fields, local parameters
final FinalClass fc = someFC; //need to assign straight away. otherwise compile error.
final FinalClass fc; //compile error, need assignment (initialization inside a constructor Ok, constructor can be called only once)
final FinalClass fc = new FinalClass(); //ok
fc = someOtherFC; //compile error
fc.someMethod(); //no problem
someOtherFC.someMethod(); //no problem
For method parameters
void someMethod(final String s){
s = someOtherString; //compile error
}
This simply means that value of the final reference value cannot be changed. i.e. only one initialization is allowed. In this scenario, in run time, since JRE knows that values cannot be changed, it loads all these finalized values (of final references) into L1 cache. Because it doesn't need to load back again and again from main memory. Otherwise it loads to L2 cache and does time to time loading from main memory. So it is also a performance improvement.
So in all above 3 scenarios, when we have not specified the final keyword in places we can use, we don't need to worry, compiler optimizations will do that for us. There are also lots of other things that compiler optimizations do for us. :)
Above all are correct. Further if you do not want others to create sub classes from your class, then declare your class as final. Then it becomes the leaf level of your class tree hierarchy that no one can extend it further. It is a good practice to avoid huge hierarchy of classes.
I can only say in answer to your question that in this case you can't change reference value of foo. You just simply put value into the same reference, that's why you can add value into the foo reference. This problem is occur you can't understand very well difference between reference value and primitive value. Reference value is also a value which store object address(this is value) in heap memory.
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
but in this case you can see that if you try to write in the following code you will see that compile time error will occur.
public static void main(String[] args)
{
Main main = new Main();
main.foo=new ArrayList<>();//Cannot assign a value to final variable 'foo'
System.out.println("print - " + main.foo);
}

Difference between Static and final?

I'm always confused between static and final keywords in java.
How are they different ?
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 this or super keywords 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 static since 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 final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final.
A final method 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 final variable 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 a blank final variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.
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.
The two really aren't similar. static fields are fields that do not belong to any particular instance of a class.
class C {
public static int n = 42;
}
Here, the static field n isn't associated with any particular instance of C but with the entire class in general (which is why C.n can be used to access it). Can you still use an instance of C to access n? Yes - but it isn't considered particularly good practice.
final on the other hand indicates that a particular variable cannot change after it is initialized.
class C {
public final int n = 42;
}
Here, n cannot be re-assigned because it is final. One other difference is that any variable can be declared final, while not every variable can be declared static.
Also, classes can be declared final which indicates that they cannot be extended:
final class C {}
class B extends C {} // error!
Similarly, methods can be declared final to indicate that they cannot be overriden by an extending class:
class C {
public final void foo() {}
}
class B extends C {
public void foo() {} // error!
}
static means there is only one copy of the variable in memory shared by all instances of the class.
The final keyword just means the value can't be changed. Without final, any object can change the value of the variable.
final -
1)When we apply "final" keyword to a variable,the value of that variable remains constant.
(or)
Once we declare a variable as final.the value of that variable cannot be changed.
2)It is useful when a variable value does not change during the life time of a program
static -
1)when we apply "static" keyword to a variable ,it means it belongs to class.
2)When we apply "static" keyword to a method,it means the method can be accessed without creating any instance of the class
Think of an object like a Speaker. If Speaker is a class, It will have different variables such as volume, treble, bass, color etc. You define all these fields while defining the Speaker class. For example, you declared the color field with a static modifier, that means you're telling the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated.
Declaring
static final String color = "Black";
will make sure that whenever this class is instantiated, the value of color field will be "Black" unless it is not changed.
public class Speaker {
static String color = "Black";
}
public class Sample {
public static void main(String args[]) {
System.out.println(Speaker.color); //will provide output as "Black"
Speaker.color = "white";
System.out.println(Speaker.color); //will provide output as "White"
}}
Note : Now once you change the color of the speaker as final this code wont execute, because final keyword makes sure that the value of the field never changes.
public class Speaker {
static final String color = "Black";
}
public class Sample {
public static void main(String args[]) {
System.out.println(Speaker.color); //should provide output as "Black"
Speaker.color = "white"; //Error because the value of color is fixed.
System.out.println(Speaker.color); //Code won't execute.
}}
You may copy/paste this code directly into your emulator and try.
Easy Difference,
Final : means that the Value of the variable is Final and it will not change anywhere. If you say that final x = 5 it means x can not be changed its value is final for everyone.
Static : means that it has only one object. lets suppose you have x = 5, in memory there is x = 5 and its present inside a class. if you create an object or instance of the class which means there a specific box that represents that class and its variables and methods. and if you create an other object or instance of that class it means there are two boxes of that same class which has different x inside them in the memory. and if you call both x in different positions and change their value then their value will be different. box 1 has x which has x =5 and box 2 has x = 6. but if you make the x static it means it can not be created again.
you can create object of class but that object will not have different x in them.
if x is static then box 1 and box 2 both will have the same x which has the value of 5. Yes i can change the value of static any where as its not final. so if i say box 1 has x and i change its value to x =5 and after that i make another box which is box2 and i change the value of box2 x to x=6. then as X is static both boxes has the same x. and both boxes will give the value of box as 6 because box2 overwrites the value of 5 to 6.
Both final and static are totally different. Final which is final can not be changed. static which will remain as one but can be changed.
"This is an example. remember static variable are always called by their class name. because they are only one for all of the objects of that class. so
Class A has x =5, i can call and change it by A.x=6; "
Static and final have some big differences:
Static variables or classes will always be available from (pretty much) anywhere. Final is just a keyword that means a variable cannot be changed. So if had:
public class Test{
public final int first = 10;
public static int second = 20;
public Test(){
second = second + 1
first = first + 1;
}
}
The program would run until it tried to change the "first" integer, which would cause an error. Outside of this class, you would only have access to the "first" variable if you had instantiated the class. This is in contrast to "second", which is available all the time.
Static is something that any object in a class can call, that inherently belongs to an object type.
A variable can be final for an entire class, and that simply means it cannot be changed anymore. It can only be set once, and trying to set it again will result in an error being thrown. It is useful for a number of reasons, perhaps you want to declare a constant, that can't be changed.
Some example code:
class someClass
{
public static int count=0;
public final String mName;
someClass(String name)
{
mname=name;
count=count+1;
}
public static void main(String args[])
{
someClass obj1=new someClass("obj1");
System.out.println("count="+count+" name="+obj1.mName);
someClass obj2=new someClass("obj2");
System.out.println("count="+count+" name="+obj2.mName);
}
}
Wikipedia contains the complete list of java keywords.
I won't try to give a complete answer here. My recommendation would be to focus on understanding what each one of them does and then it should be cleare to see that their effects are completely different and why sometimes they are used together.
static is for members of a class (attributes and methods) and it has to be understood in contrast to instance (non static) members. I'd recommend reading "Understanding Instance and Class Members" in The Java Tutorials. I can also be used in static blocks but I would not worry about it for a start.
final has different meanings according if its applied to variables, methods, classes or some other cases. Here I like Wikipedia explanations better.
Static variable values can get changed although one copy of the variable traverse through the application, whereas Final Variable values can be initialized once and cannot be changed throughout the application.

What is the significance of final instance variables?

I am having some confusion between static final class variable and final instance variable.
Here is the sample code:-
class Foof{
final int size=3;
final int whuffie;
Foof()
{
whuffie=42;
}
public static void main(String [] args){
Foof obj1 = new Foof();
Foof obj2 = new Foof();
obj1.size=53; //compile time error
System.out.println(obj1.size);
obj2.whuffie=45; //compile time error
System.out.println(obj2.whuffie);
}
}
Error:-
ankit#stream:/home/Data/JAVA/practice/src/test.com/test-20121031_static_demystified$ javac Foof.java
Foof.java:14: error: cannot assign a value to final variable size
obj1.size=53; //compile time error
^
Foof.java:16: error: cannot assign a value to final variable whuffie
obj2.whuffie=45;
^
2 errors
So my question is, what is the point of having final instance variables if they can't have a different values per different instance. I mean if they have same value for each instance then why don't we declare them as class variable(static final class variable) as this would serve the same purpose and the we don't need to create objects in order to access them.
EDIT -1:-
class Foof{
final int size=3;
final int whuffie;
Foof()
{
whuffie=42;
size = 23; //compile-time error.
}
public static void main(String [] args){
Foof obj1 = new Foof();
Foof obj2 = new Foof();
//obj1.size=53;
System.out.println(obj1.size);
//obj2.whuffie=45;
System.out.println(obj2.whuffie);
}
}
Error:-
Foof.java:8: cannot assign a value to final variable size
size = 23;
^
1 error
According to the error, i can make out that first size is assigned a value =3 during object creation.
So my question is, what is the point of having final instance variables if they can't have a different values per different instance.
They can, but those values can't be changed after creation. You can only assign values to final instance fields within instance variable initializers and constructors, and you must assign values to all instance fields that way.
Note that in your code here:
Foof()
{
whuffie=42; //compile time error
}
... the comment is incorrect. That assignment should be perfectly valid.
Final fields are useful for implementing immutability - which helps make it easy to reason about an object. For example, String is immutable, so if you validate a string and then keep a copy of the reference, you know that validation will still be correct later on.
Compare that with java.util.Date, where if you really want to have any faith in validation being useful, you need to create a defensive copy of the Date value and not provide the reference to any other code, in case it changes the underlying instant being represented.
A final is final as soon as you asign a value to it. You can't change it later.
You can't modify a final variable after initializing on declaration or in the constructor(s).
Using the static keyword doesn't make it modifiable. It just means the final variable can be accessed through the class name or instance variable, the variable is still immutable.
Actually static and non static final variable are needs when we are creating any varible as a class specific then will declare it as static and if object level then will declare it as non static variable.
For example,
We have a country as a class and and will have two data members of that class like
timezone and gravity.
we declred both of them as final, but timezone is object specific(timezone of every country is different but same throughout the country) and gravity is class specific(gravity of each country is same as earths gravity) so we are declared gravity as static final.
final variables are typically used to define things that should never change. You can write to it one time and then it is set forever.
You might use this in a constructor to set an ID for an object or something similar.
For final variables you can assign value only once.
It is generally used in case where you don't want the values of variables to be changed later in your program.
Static variables only one instance is created per class, irrespective of number of objects of that class you create.

Categories

Resources