Related
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'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 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
Building a multi-language application in Java. Getting an error when inserting String value from R.string resource XML file:
public static final String TTT = (String) getText(R.string.TTT);
This is the error message:
Error: Cannot make a static reference to the non-static method getText(int) from the type
Context
How is this caused and how can I solve it?
Since getText() is non-static you cannot call it from a static method.
To understand why, you have to understand the difference between the two.
Instance (non-static) methods work on objects that are of a particular type (the class). These are created with the new like this:
SomeClass myObject = new SomeClass();
To call an instance method, you call it on the instance (myObject):
myObject.getText(...)
However a static method/field can be called only on the type directly, say like this:
The previous statement is not correct. One can also refer to static fields with an object reference like myObject.staticMethod() but this is discouraged because it does not make it clear that they are class variables.
... = SomeClass.final
And the two cannot work together as they operate on different data spaces (instance data and class data)
Let me try and explain. Consider this class (psuedocode):
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = "0";
}
Now I have the following use case:
Test item1 = new Test();
item1.somedata = "200";
Test item2 = new Test();
Test.TTT = "1";
What are the values?
Well
in item1 TTT = 1 and somedata = 200
in item2 TTT = 1 and somedata = 99
In other words, TTT is a datum that is shared by all the instances of the type. So it make no sense to say
class Test {
string somedata = "99";
string getText() { return somedata; }
static string TTT = getText(); // error there is is no somedata at this point
}
So the question is why is TTT static or why is getText() not static?
Remove the static and it should get past this error - but without understanding what your type does it's only a sticking plaster till the next error. What are the requirements of getText() that require it to be non-static?
There are some good answers already with explanations of why the mixture of the non-static Context method getText() can't be used with your static final String.
A good question to ask is: why do you want to do this? You are attempting to load a String from your strings resource, and populate its value into a public static field. I assume that this is so that some of your other classes can access it? If so, there is no need to do this. Instead pass a Context into your other classes and call context.getText(R.string.TTT) from within them.
public class NonActivity {
public static void doStuff(Context context) {
String TTT = context.getText(R.string.TTT);
...
}
}
And to call this from your Activity:
NonActivity.doStuff(this);
This will allow you to access your String resource without needing to use a public static field.
for others that find this in the search:
I often get this one when I accidentally call a function using the class name rather than the object name. This typically happens because i give them too similar names : P
ie:
MyClass myclass = new MyClass();
// then later
MyClass.someFunction();
This is obviously a static method. (good for somethings)
But what i really wanted to do (in most cases was)
myclass.someFunction();
It's such a silly mistake, but every couple of months, i waste about 30 mins messing with vars in the "MyClass" definitions to work out what im doing wrong when really, its just a typo.
Funny note: stack overflow highlights the syntax to make the mistake really obvious here.
You can either make your variable non static
public final String TTT = (String) getText(R.string.TTT);
or make the "getText" method static (if at all possible)
getText is a member of the your Activity so it must be called when "this" exists. Your static variable is initialized when your class is loaded before your Activity is created.
Since you want the variable to be initialized from a Resource string then it cannot be static. If you want it to be static you can initialize it with the String value.
You can not make reference to static variable from non-static method.
To understand this , you need to understand the difference between static and non-static.
Static variables are class variables , they belong to class with their only one instance , created at the first only.
Non-static variables are initialized every time you create an object of the class.
Now coming to your question, when you use new() operator we will create copy of every non-static filed for every object, but it is not the case for static fields. That's why it gives compile time error if you are referencing a static variable from non-static method.
This question is not new and existing answers give some good theoretical background. I just want to add a more pragmatic answer.
getText is a method of the Context abstract class and in order to call it, one needs an instance of its subclass (Activity, Service, Application or other). The problem is, that the public static final variables are initialized before any instance of Context is created.
There are several ways to solve this:
Make the variable a member variable (field) of the Activity or other subclass of Context by removing the static modifier and placing it within the class body;
Keep it static and delay the initialization to a later point (e.g. in the onCreate method);
Make it a local variable in the place of actual usage.
Yes u can make call on non-static method into static method because we need to remember first' we can create an object that's class we can call easyly on non -static method into static mathod