I have a function multi2 which returns inner class Inner as an Object.
What happens to a - where is it saved and how can I access it?
public class C {
private static Object multi2(final int a) {
class Inner {
public int hashCode() {
return 2*a;
}
}
return new Inner(); // What happens to a?
// Who allocates a?
// Can I Access a?
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
}
}
What happens at the implementation level is that a copy of the value of a is saved in a synthetic instance variable declared in the compiled version of the C.Inner class.
The value of a is passed to the compiled Inner constructor via an extra parameter.
The C.Inner.hashCode method uses the value of the synthetic variable. Accessing a in the source code of Inner.hashCode is transformed into accessing the corresponding synthetic variable in the compiled code.
The variable in the outer scope must be final1. The synthetic variable must be final2 in the Inner class. This maintains the illusion that (potentially) multiple instances of the Inner class are seeing the same a variable. (They aren't, but since the variable(s) can't be changed, it is not possible for the code of the inner class to tell the difference.)
If you use javap to look at the bytecodes for the compiled example, you will see the mechanisms used to implement this in the outer and the inner classes.
1 - or effectively final from Java 8 onwards.
2 - If a could be mutated by an Inner method, then two Inner instances with the same outer class need to share a mutable variable whose lifetime is (now) longer than the stackframe for a multi2 call. That entails somehow turning a from stack variable into something that lives on the heap. It would be expensive and complicated.
You have defined the class Inner inside the function so the scope of the class will be
restricted with in the method. And your function is static so it will be live as long as the class definition is loaded. You have override the hashCode function inside the InnerClass so every time you are calling the multi2(param) you are creating the hashCode for the instance of InnerClass and returning the instance of the InnerClass.
So as for you questions, please correct me if i am wrong.
What happens to a ?
a is with in the scope of your static method, so it will be live as long as the class definition is loaded.
Who allocates a?
scope of a is restricted inside the static method and static method does not require instance to access it but as for the static method/variable allocation, i think it depends on JVM.
Can I Access a?
No you cannot access a from outside you static method, it is restricted with in your static method.
Since the "a" is a local parameter, you could use a different approach to read the "a" value:
public class C {
public static Object multi2(final int a) {
return new Inner(a);
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
}
}
class Inner{
public int valueA;
public Inner(int a)
{
valueA = a;
}
public int getA() {
return valueA;
}
public int hashCode() {
return 2*valueA;
}
}
I wanted to know what was actually happening, so I compiled your code and looked at the bytecode output.
Basically what happens is the compiler adds in a constructor to your class 'Inner'. It also adds a single parameter to that constructor which takes 'a'. If your multi2() method was NOT static then there would probably also be a parameter to take 'this' where 'this' is the instance of 'C' that multi2() is executing on. BUT since we're in static context, there is no 'this'.
The compiler adds a private final field to your class 'Inner' and sets that private field using the value passed via the constructor. The compiler also converts
new Inner()
into
new Inner(a)
Hashcode then accesses the private field containing the value for a.
If 'a' was an object instead of a primitive, then it would be the same way, but a reference would be passed through instead of an actual number value.
How do you access this variable? Well you access it with reflections, but there are many problems:
1) You don't know the name of the field made by the compiler, so you can only get the name by looking at the bytecode. Don't trust decompilers as they might change the name. You gotta look at the bytecode yourself to find out.
2) The compiler probably marks the field as final, which means even if you can get reflections to access the field for you, you won't be able to update it.
3) It is entirely up to the compiler to figure out field names. Field names could change between builds depending on the compiler and it's mood.
Inner is a so called local class. a is a parameter passed to the method multi2 and accessable within that scope. Outside of that method, you cannot access a.
What is the difference between a static and instance variable. The following sentence is what I cant get:
In certain cases, only one copy of a particular variable should be shared by all objects of a class- here a static variable is used.
A static variable represents class wide info.All objects of a class share the same data.
I thought that instance vars were used class wide whereas static variables only had scope within their own methods?
In the context of class attributes, static has a different meaning. If you have a field like:
private static int sharedAttribute;
then, each and every instance of the class will share the same variable, so that if you change it in one instance, the change will reflect in all instances, created either before or after the change.
Thus said, you might understand that this is bad in many cases, because it can easiy turn into an undesired side-effect: changing object a also affects b and you might end up wondering why b changed with no apparent reasons. Anyway, there are cases where this behaviour is absolutely desirable:
class constants: since they are const, having all the classes access the same value will do no harm, because no one can change that. They can save memory too, if you have a lot of instances of that class. Not sure about concurrent access, though.
variables that are intended to be shared, such as reference counters &co.
static vars are instantiated before your program starts, so if you have too many of them, you could slow down startup.
A static method can only access static attributes, but think twice before trying this.
Rule of thumb: don't use static, unless it is necessary and you know what you are doing or you are declaring a class constant.
Say there is a test class:
class Test{
public static int a = 5;
public int b = 10;
}
// here t1 and t2 will have a separate copy of b
// while they will have same copy of a.
Test t1 = new test();
Test t2 = new test();
You can access a static variable with it's class Name like this
Test.a = 1//some value But you can not access instance variable like this
System.out.println(t1.a);
System.out.println(t2.a);
In both cases output will be 1 as a is share by all instances of the test class.
while the instance variable will each have separate copy of b (instance variable)
So
t1.b = 15 // will not be reflected in t2.
System.out.println(t1.b); // this will print 15
System.out.println(t2.b); / this will still print 10;
Hope that explains your query.
Suppose we create a static variable K and in the main function we create three objects:
ob1
ob2
ob3;
All these objects can have the same value for variable K. In contrast if the variable K was an instance variable then it could have different values as:
ob1.k
ob2.k
ob3.k
I think you are thinking about the C/C++ definition of the static keyword. There, the static keyword has many uses. In Java, the static keyword's functionality is described in your post. Anyhow, you can try it for yourself:
public class Test_Static{
static int x;
public static void main(String[] argv){
Test_Static a = new Test_Static();
Test_Static b = new Test_Static();
a.x = 1; // This will give an error, but still compile.
b.x = 2;
System.out.println(a.x); // Should print 2
}
}
and similarly for non static variables:
public class Test_NonStatic{
int x;
public static void main(String [] argv){
Test_NonStatic a = new Test_NonStatic();
Test_NonStatic b = new Test_NonStatic();
a.x = 1;
b.x = 2;
System.out.println(a.x); // Should print 1.
}
}
Consider a class MyClass, having one static and one non-static member:
public class MyClass {
public static int STATICVARIABLE = 0;
public int nonStaticVariable = 0;
}
Now, let's create a main() to create a couple of instances:
public class AnotherClass{
public static void main(String[] args) {
// Create two instances of MyClass
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
obj1.nonStaticVariable = 30; // Setting value for nonstatic varibale
obj1.STATICVARIABLE = 40; //Setting value for static variable
obj2.nonStaticVariable = 50;
obj2.STATICVARIABLE = 60;
// Print the values actually set for static and non-static variables.
System.out.println(obj1.STATICVARIABLE);
System.out.println(obj1.nonStaticVariable);
System.out.println(obj2.STATICVARIABLE);
System.out.println(obj2.nonStaticVariable);
}
}
Result:
60
30
60
50
Now you can see value of the static variable printed 60 both the times, as both obj1 and obj2 were referring to the same variable. With the non-static variable, the outputs differ, as each object when created keeps its own copy of non-static variable; changes made to them do not impact on the other copy of the variable created by another object.
Instance Variables
Any variable that is defined in class body and outside bodies of
methods; and it should not be declared static, abstract, stricftp,
synchronized, and native modifier.
An instance variable cannot live without its object, and it is a part of
the object.
Every object has their own copies of instance variables.
Static Variables (class variables)
Use static modifier
Belong to the class (not to an object of the class)
One copy of a static variable
Initialize only once at the start of the execution.
Enjoy the program’s lifetime
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);
}
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.