When are static variables initialized? - java

I am wondering when static variables are initialized to their default values.
Is it correct that when a class is loaded, static vars are created (allocated),
then static initializers and initializations in declarations are executed?
At what point are the default values are given? This leads to the problem of forward reference.
Also please if you can explain this in reference to the question asked on Why static fields are not initialized in time? and especially the answer given by Kevin Brock on the same site. I can't understand the 3rd point.

From See Java Static Variable Methods:
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.
Instance and class (static) variables are automatically initialized to standard default values if you fail to purposely initialize them. Although local variables are not automatically initialized, you cannot compile a program that fails to either initialize a local variable or assign a value to that local variable before it is used.
What the compiler actually does is to internally produce a single class initialization routine that combines all the static variable initializers and all of the static initializer blocks of code, in the order that they appear in the class declaration. This single initialization procedure is run automatically, one time only, when the class is first loaded.
In case of inner classes, they can not have static fields
An inner class is a nested class that is not explicitly or implicitly
declared static.
...
Inner classes may not declare static initializers (§8.7) or member interfaces...
Inner classes may not declare static members, unless they are constant variables...
See JLS 8.1.3 Inner Classes and Enclosing Instances
final fields in Java can be initialized separately from their declaration place this is however can not be applicable to static final fields. See the example below.
final class Demo
{
private final int x;
private static final int z; //must be initialized here.
static
{
z = 10; //It can be initialized here.
}
public Demo(int x)
{
this.x=x; //This is possible.
//z=15; compiler-error - can not assign a value to a final variable z
}
}
This is because there is just one copy of the static variables associated with the type, rather than one associated with each instance of the type as with instance variables and if we try to initialize z of type static final within the constructor, it will attempt to reinitialize the static final type field z because the constructor is run on each instantiation of the class that must not occur to static final fields.

Static fields are initialized when the class is loaded by the class loader. Default values are assigned at this time. This is done in the order than they appear in the source code.

See:
JLS 8.7, Static Initializers
JLS 12.2, Loading of Classes and Interfaces
JLS 12.4, Initialization of Classes and Interfaces
The last in particular provides detailed initialization steps that spell out when static variables are initialized, and in what order (with the caveat that final class variables and interface fields that are compile-time constants are initialized first.)
I'm not sure what your specific question about point 3 (assuming you mean the nested one?) is. The detailed sequence states this would be a recursive initialization request so it will continue initialization.

The order of initialization is:
Static initialization blocks
Instance initialization blocks
Constructors
The details of the process are explained in the JVM specification document.

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(when the Classloader load the class for the first time) .
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

Starting with the code from the other question:
class MyClass {
private static MyClass myClass = new MyClass();
private static final Object obj = new Object();
public MyClass() {
System.out.println(obj); // will print null once
}
}
A reference to this class will start initialization. First, the class will be marked as initialized. Then the first static field will be initialized with a new instance of MyClass(). Note that myClass is immediately given a reference to a blank MyClass instance. The space is there, but all values are null. The constructor is now executed and prints obj, which is null.
Now back to initializing the class: obj is made a reference to a new real object, and we're done.
If this was set off by a statement like: MyClass mc = new MyClass(); space for a new MyClass instance is again allocated (and the reference placed in mc). The constructor is again executed and again prints obj, which now is not null.
The real trick here is that when you use new, as in WhatEverItIs weii = new WhatEverItIs( p1, p2 ); weii is immediately given a reference to a bit of nulled memory. The JVM will then go on to initialize values and run the constructor. But if you somehow reference weii before it does so--by referencing it from another thread or or by referencing from the class initialization, for instance--you are looking at a class instance filled with null values.

The static variable can be intialize in the following three ways as follow choose any one you like
you can intialize it at the time of declaration
or you can do by making static block eg:
static {
// whatever code is needed for initialization goes here
}
There is an alternative to static blocks — you can write a private static method
class name {
public static varType myVar = initializeVar();
private static varType initializeVar() {
// initialization code goes here
}
}

Related

Java - Is it ok to instantiate class objects inside class? [duplicate]

Why can we access a static variable via an object reference in Java, like the code below?
public class Static {
private static String x = "Static variable";
public String getX() {
return this.x; // Case #1
}
public static void main(String[] args) {
Static member = new Static();
System.out.println(member.x); // Case #2
}
}
Generally, public variables can be accessed by everybody, and private variables can only be accessed from within the current instance of the class. In your example you're allowed to access the x variable from the main method, because that method is within the Static class.
If you're wondering why you're allowed to access it from another instance of Static class than the one you're currently in (which generally isn't allowed for private variables), it's simply because static variables don't exist on a per-instance basis, but on a per class basis. This means that the same static variable of A can be accessed from all instances of A.
If this wasn't the case, nobody would be able to access the private static variable at all, since it doesn't belong to one instance, but them all.
The reason that it is allowed is that the JLS says it is. The specific sections that allows this are JLS 6.5.6.2 (for the member.x cases) and JLS 15.11.1 (in both cases). The latter says:
If the field is static:
If the field is a non-blank final field, then the result is the value of the specified class variable in the class or interface that is the type of the Primary expression.
If the field is not final, or is a blank final and the field access occurs in a class variable initializer (§8.3.2) or static initializer (§8.7), then the result is a variable, namely, the specified class variable in the class that is the type of the Primary expression.
Why are these allowed by the JLS?
Frankly, I don't know. I can't think of any good reasons to allow them.
Either way, using a reference or this to access a static variable is a bad idea because most programmers are likely to be mislead into thinking that you are using an instance field. That is a strong reason to not use this feature of Java.
In your first and second cases you should reference the variable as x or Static.x rather than member.x. (I prefer Static.x.)
It is not best practice to reference a static variable in that way.
However your question was why is it allowed? I would guess the answer is to that a developer can change an instance member (field or variable) to a static member without having to change all the references to that member.
This is especially true in multi-developer environments. Otherwise your code may fail to compile just because your partner changed some instance variables to static variables.
static variables are otherwise called as class variables, because they are available to each object of that class.
As member is an object of the class Static, so you can access all static as wll as non static variables of Static class through member object.
The non-static member is instance member. The static member(class wide) could not access instance members because, there are no way to determine which instance owns any specific non-static members.
The instance object could always refers to static members as it belongs to class which global(shared) to its instances.
This logically makes sense although it is not interesting practice. Static variable is usually for enforcing single declaration of variable during instantiation. Object is a new copy of Class with other name. Even though object is new copy of class it is still with characteristics of the (uninstantiated) Class (first invisible instance). Therefore new object also has that static members pointing to the original copy. Thing to note is: New instance of StackOverflow is also StackOverflow.

What does ObjectReference.VariableName mean?

I didn't understand this part:
Instance variables can be accessed directly by calling the variable name inside the class. However, within static methods (when instance variables are given accessibility), they should be called using the fully qualified name. ObjectReference.VariableName.
Can you give an example please ?
Static methods are methods that are called without a reference to an instance of that object. So instance variables cannot be called statically, as each instance will have its own values. So in a static method, you need a specific instance of an object in order to know which value of the instance variable you are trying to use.
The difference is how you access these variables:
class myClass {
public static int staticVar;
public int nonStaticVar;
//Constructor initialises both
}
Static approach:
int otherVariable = MyClass.staticVar;
As you can see, for the static variable you do not need to make an object to access it. Note that you can imagine a static variable to have the trait "once per class", which means, that you can not have 2 versions of staticVar.
Non Static (instance variable):
MyClass instanceOfMyClass = new myClass();
int otherVariable2 = instanceOfMyClass.nonStaticVar;
To have 2 versions of nonStaticVar you can simply make 2 objects and give this variable different values in the 2 objects. Note that in this case you have to make an object.

When to choose variables to declare as final static

I have used final and static variables as well. what i found about these variables is,
final variable
A final variable can only be initialized once, either via an initializer or an assignment statement.
Unlike the value of a constant, the value of a final variable is not necessarily known at compile time.
what variables should i declare as final-
Most often i use those variables whose value is constant universally and can never changed, such as the value of PI.
public static final double PI = 3.141592653589793;
static variables
These are those variables which belongs to the class and not to object(instance).
Static variables are initialized only once , at the start of the execution .
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.
what variables should i declare as final-
Most of the time, i use those variables which i want to initialize only once and use them in the enitre class.
When to use final static variable
Now, i came across a term final static in one of my database project. I found that some of the database objects or even database version were declared as statci final.
static final String DATA_BASE = "BackUpDatabase.db";
static final int DATA_BASE_VERSION = 1;
Now, my question is what variables should we declare as final or static or final static, as using either of them could have solved the issue, then wyh to use both together.
static - Only use when a variable which is used globally
final - Only use when you need to declare a value as constant
static final - Only use when a value is globally used and it is a constant.
: - Here global means across all the instances of a java class
Variables declared as static final (or vice versa) are understood to be meaningful constants, and are named in all upper-case with underscores for spaces.
An example of a commonly encountered constant is Integer.MAX_VALUE, or Math.PI.
final only says that value once initialized can't be changed; static says that the attribute belongs to Class and NOT objects.
So when you say final static; this means there is just one copy of variable and it can't be changed.
- static in java means Class's member. Its shared by all the instances of the class.
- final keyword in java means, constant, but has different interpretation depending on what its being applied.
- When we use static final on a field, consider it as a Global variable.
- PI is static variable of Math Class and its directly accessed using the class name, as Math.PI.
- Use all letters in caps to define a static final variable.
final's interpretation:
final variable : Its value canNot be changed
final method : It canNot be overridden
final class : It canNot be extended
final Parameter : Its value canNot be changed which it receives from caller's argument
final Object Reference Variable : It canNot refer to any other object, other than the one its currently referring to
Declaring variables only as static can lead to change in their values by one or more instances of a class in which it is declared.
Declaring them as static final will help you to create a CONSTANT as #Vulcan told. Only one copy exists which can be accessed anywhere.
Static Variable
You can change the static variable value by calling static method
present in same class .
Static variable value will be same for all object created from this
class . if we change the value then all object of that class will get
new value ,old value will be lost.
Value can be changed multiple times.
Final variable
This variable value can be initialized by two way:
At the time of declaring the variable.
At the time of creating object of that class where class constructor will have this.finalvariable = newfinalvariablevalue;
Once initialized it can't be changed by any method (Static or non-static).
static methods or classes are implicitly final .
Because there is only one copy of this method existing for all the objects which means that subclasses dont have access to modify the copy.
lets say you have a method in the parent and you dont want subclasses to change this method.. just declare the parent method as a final. Here you go.
class Parent {
final void myMethod() {
//No one can change this method from subclassess
//compiler works efficiently because it knows that this method will not change
}
}
class Child extends Parent{
//from this class I can use myMethod but I cannot override.
}

java static instance fields and constructor

In a Java class with static instance fields, is the constructor called every time the fields are accessed, or only on the first access? I initialize the static fields in the constructor, and was wondering if this would cause a slow down because the fields are initialized on every access.
I initialize the static fields in the constructor,
Don't. Never initialize static fields inside a constructor. static fields are not something associated with any instance of a class. It is bound to class. There is only single copy of that variable, that is accessed accross all the instances. So, if you are initializing it in constructor, then every time you create an instance, that field will be re-initialized for every other instance.
You should use static initializer block to initialize your static fields, or just initialize them at the place of declaration.
class Demo {
private static int x; // Either initialize it here.
static { // Or use static initializer block
x = 10;
}
}
with static instance fields, is the constructor called every time the fields are accessed,
No. , static fields are accessed on class. They are loaded and initialized when the class is loaded. And then you can modify it later on, on class name, in which case, the change will be effected for all the instances. So, the constructor will not be invoked, whenever you access static field.
In fact, even when you access instance field, constructor is not invoked every time. Constructor is used to initialize the state of the newly created instance once. And for further access and modification of that field, constructor won't be invoked.
So, a constructor has precisely no role to play whenever you want to access any fields of your class.
The constructor for the object of the static field is called only once, at some point before the field is accessed for the first time. You should not initialize static fields in a regular instance constructor. If they need special initialization, you should supply a static initialization block, like this:
public class Test {
static int[][] a = new int[20][];
static {
for (int i = 0 ; i != 20 ; i++) {
a[i] = new int[i+1];
}
}
}
static variables are loaded when the class is loaded. And only once.
According to the JLS:
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized
So this answers your question. i.e.e exactly when the class is loaded :)
Static variables lasts till the JVM is shutdown.

SubClass variables do not get initialized again

I have my main class from which i call my sub class.
My sub class contains some public static variables like
public class SubClass2 extends Main {
public static long a = 0;
public static long b = 0;
public static long c= 0;
public void Analyze(int number)
{
b=2;
//some code
}
}
Where as in main i call the object of the SubClass2.I want everytime when i make the new object of the subclass2 in main then it initializes
all the variables =0 but when i take the print statement of the variable b.It prints out like 4.It adds up the previous value with the new value.
Your fields should not be declared as static in that case. This is why they're not being initialised each time. A static field is initialised once only, then shared by every instance of the class, and depending on accessibility, also outside of the class.
The logic that led to the value 4 must be in the code you've replaced with //some code, but this ins't really relevant here.
If for whatever reason these really should be static fields that are initialised each time an instance is instantiated, then you would have to initialise them manually in the class's constructor. But I'd seriously question the design that leads to this situation...
You are using static variables. These have no connection to any objects you create. They are just global, unique variables. You must erase static. By the way, it is redundant to initialize a field to 0. It is already initialized to zero.
If you use the word static there will only ever be one instance of the variable that is shared between everything created that uses it. Remove static and there will be a new, but more importantly, individual variable for each time its initialised in a method.
Perhaps better wording is that instance methods can and will access shared/static variables!
Your question embodies a contradiction in terms. Static variables are initialized once, when the class is loaded. If you want variables initialized per-instance, use per-instance (non-static) variables.

Categories

Resources