This question already has an answer here:
Are there any guarantees in JLS about order of execution static initialization blocks?
(1 answer)
Closed 8 years ago.
Is there a reason where static final variable will not be instantiated before the static block?
So in the example I provided will print:
someVar value= null
Instead of:
someVar value=SomeValue
I saw this behavior today, In my application,
I am trying to reproduce - unsuccessfully - I do see the value of the static member...
class SomeClass{
static final String someVar ="SomeValue";
static{
System.out.println("someVar value=" + someVar );
}
public static void main(String[] args){
new SomeClass();
}
}
The order of initialization is given in JSL #12.4.2:
For static initialization:
Execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
For construction:
Evaluate the arguments and process that superclass constructor invocation recursively
Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class.
Execute the rest of the body of this constructor.
Note that initializer blocks and variable initializers are considered together, not separately.
I would to say, it depend on your code sequence. Run following code in your local, it will tell you the answer.
public class SomeClass{
static final String someVar ="SomeValue";
static final StaticMember staticMem = new StaticMember(1);
static{
System.out.println("someVar value=" + someVar );
}
static final StaticMember staticMem2 = new StaticMember(2);
public static void main(String[] args){
new SomeClass();
}
}
class StaticMember {
StaticMember(int num) {
System.out.println("StaticMember constructor " + num);
}
}
There is an order the jvm will excecute and instanciate always in this priority:
Static Blocks
Static Members
Instance Blocks
Instance Members
Constructor
If you have inheritance the instanciation order will be a little bit different:
Parent Static Block
Parent Static Members
Child Static Block
Child Static Members
Parent Non-Static Members
Child Non-Static Members
Parent Constructor
Child Constructor
I hope this clarifies a little your issue.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java static class initialization
Why is the string variable updated in the initialization block and not the integer(even though the block is written first)
class NewClass
{
static
{
System.out.println(NewClass.string+" "+NewClass.integer);
}
final static String string="static";
final static Integer integer=1;
public static void main(String [] args)//throws Exception
{
}
}
My output is
static null
P.S:Also noticed that string variable initialization happens before the block only when i insert the final modifier. why is that?why not for integer as well?I have declared it as final static too
From section 12.4.2 of the JLS, snipped appropriately:
The procedure for initializing C is then as follows:
Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).
Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
So for non-compile-time-constants, it's not a case of "all variables" and then "all static initializers" or vice versa - it's all of them together, in textual order. So if you had:
static int x = method("x");
static {
System.out.println("init 1");
}
static int y = method("y");
static {
System.out.println("init 2");
}
static int method(String name) {
System.out.println(name);
return 0;
}
Then the output would be:
x
init 1
y
init 2
Even making x or y final wouldn't affect this here, as they still wouldn't be compile-time constants.
P.S:Also noticed that string variable initialization happens before the block only when i insert the final modifier.
At that point, it's a compile-time constant, and any uses of it basically inlined. Additionally, the variable value is assigned before the rest of the initializers, as above.
Section 15.28 of the JLS defines compile-time constants - it includes all primitive values and String, but not the wrapper types such as Integer.
Here is a short and straight forward answer to you question....
static Variable :
static Variables are executed when the JVM loads the Class, and the Class gets loaded when either its been instantiated or its static method is being called.
static Block or static Initializer Block :
static static Initializer Block gets Initialized before the Class gets instantiated or before its static method is called, and Even before its static variable is used.
///////// Edited Part /////////
class NewClass {
final static String string = "static";
final static Integer integer = 1;
static {
System.out.println(NewClas.string + " " + NewClas.integer);
}
public static void main(String [] args) { // throws Exception
new NewClas();
}
}
The above will print static 1.
The reason is that the JVM will do the optimization process known as Constant folding, doing an pre-calculation of the constant variables.
Moreover in your case the result was static null cause Constant folding is applied to Primitive type and not Wrapper Object, in your case its Integer...
They are initialized in the given order (fields and static blocks), that's why printed value is null, nothing was assigned to static fields that are defined after the static block.
What is the problem with below code?
class test {
static int a;
a=10;
}
If I'm writing like this (as above), I'm getting a compile time error.
class test {
static int a=10;
a=4;
}
For the second one, I'm not getting any error.
Neither of your examples should compile.
a=10;
is a statement, which is not valid directly inside a class declaration. You can only put the following directly inside a class:
Member declarations (member/static variable declarations (like static int a;), methods, nested classes and interfaces);
Static and instance initializers;
Constructors.
You need to put a statement inside a block, for example a static initializer:
static int a;
static {
a = 10;
}
which is equivalent to:
static int a = 10;
You need to use a static block of statement to do an assignment on an other line (outside a method)
class test {
static int a;
static { a=10; }
}
a=4; must be done in a valid scope
either a method or a constructor...
this line is valid instead
static int a=10;
because java allows youto declare and initialize in one statement!
If you want to initialize a after defining it as a null int, you can only do that in a function, because it is static.
must be initialized inside static block or init block or in constructor.
you can only initialized your member variable after declaration inside a function or block because it is static you should use static block
What you are currently doing is declaring a variable in a class decleration, which is not valid. Looking at this neither of your examples should give you any good result.
In a class declaration you can however initialize a variable:
static int a;
Then if you want to work with it you would have to create a method first (if you are not aware of this I would strongly advise to watch some youtube tutorials or read books about this topic) :
public void foo(int a){
a = 6; //Here you can play with your variables and change them
}
In class declararions you can: declarations methods, initializers and constructors. (there is a bit more you can do, however I would have a look at these points before diving in too deep).
Furthermore it seems that you are not aware what a static variable or a static method does, I think the following posts will help you with that:
difference between 'static int' and 'int' in java
What are static method and variables?
I hope I could help and have fun learning Java
Because for static memory allocated at the time of class loading
so we need do like this
class test {static int a =10;
public static void main(String args[]) { a=12 output(test.a (or) a);}}
A Java class body is should contain declarations and declaration with an initializer, not the standalone statements. Let's unwrap your requirement of initializing a static variable.
Static variables should not be initialized inside methods as these variables belong to the class. But they can be initiated inside the constructor.
public class Example {
static String name;
static int age;
Example() {
name = "James";
age = 34;
}
public static void main(String args[]) {
new Example();
System.out.println(Example.name);
System.out.println(Example.age);
}
}
Now the output will be :
James
34
If new Example(); is not called then the output will be :
null
0
This is because the static variables are initialized with an object creation and for each Example object name and age will be overwritten with the same value. But at least one object needs to be created for name and age to be initialized.
But if you declare a static and final instance variable, we cannot initialize that in the constructor, it is mandatory to initialize static and final variables at the class level. We can initialize while declaring the variable or using a static initialization block. This runs before the main() method in Java. Hence when the main() method is loaded this static variable will be initialized and the compiler will not throw any errors.
static final int name = "STRING";
static final int age;
static {
age = 10;
}
Putting all these things together,
A static variable can be initialized,
When declaring.
Inside a constructor.
Inside a static block.
A static final variable can be initialized,
When declaring.
Inside a static block.
A final variable can be initialized,
When declaring.
Inside a constructor (If you have more than one constructor in your class then it must be initialized in all of them).
The compiler says illegal modifier for parameter i.
Please tell me what I'm doing wrong. Why can't I use a static variable in a Java constructor?
class Student5{
Student5() {
static int i = 0;
System.out.println(i++);
}
public static void main(String args[]){
Student5 c1 = new Student5();
Student5 c2 = new Student5();
Student5 c3 = new Student5();
}
}
Because of where you are declaring i:
Student5(){
static int i=0;
System.out.println(i++);
}
the compiler treats it as a local variable in the constructor:
Local variables cannot be declared as static. For details on what modifiers are allowed for local variables, see Section 14.4 of the Java Language Specification.
Judging from what the code appears to be trying to do, you probably want i to be a static member of Student5, not a local variable in the constructor:
class Student5{
private static int i = 0;
Student5(){
System.out.println(i++);
}
. . .
}
If you want to declare static variable then declare it outside of the constructor, at class level like this -
public class Student5{
private static int i;
}
You declaration of static occurred at your constructor which is a local variable and local variable can not be static. And that's why you are getting - illegal modifier for parameter i. And finally for initializing static variable you may use a static initialization block (though it's not mandatory) -
public class Student5{
private static int i;
static {
i = 5;
}
}
This is how the language was designed.. What if you wanted to have another int field named i in the constructor?, then which i should be considered?. Also, static fields are initialized before the constructor is called i.e, during class initilization phase. A constructor gets called only when a new instance is created.
Imagine what would happen (supposed to happen) if you load and initialize a class but not create a new instance.
Static variables are variables that can be referenced without having an instance of the class. By defining one instead of a constructor, which is called when you create an instance of the class, you are contradicting yourself. Either make it defined without having an instance (outside of the constructor and static) or make it specific to an instance (inside the constructor and not static).
You might want to rethink what you are actually trying to do and if you really need a static variable.
Here is example code:
class A {
static {
int a;
class B {
}
}
public static void main(String[] args){
// cannot access class B and in a;
}
}
I don't know what the static keyword in this context means. I declare an int variable and a class inside it. But I cannot use it inside class A or in the main method. I compile and it doesn't produce any errors. So, I think this type of declaration has some purpose.
This is a static initialization block. You can use this to collect initialization for static/class members.
Similarly you can have a non-static initialization block to initialize instance members for each new object:
class A
{
static int a;
private int b;
// static/class initialization:
static
{
// initialize class members
a = 5;
}
// instance initialization:
{
// initialize instance members
b = 5;
}
}
This example is trivial, you could instead just initialize the variables in their declaration: static int a = 5, and in fact generally that would be clearer. But use an initialization block when the initialization is multi-step, or generally more complicated, for example, setting up a database connection.
For more examples, see: Initializing Fields from the java tutorials.
The code inside the static {} block will be executed when the class (not an object of this class) is loaded for the first time.
See this
It is referred as static block in Java. This is usually used for initialization purposes that your Class A might require
static blocks are executed when JVM loads this class. There can be many such blocks and they would be executed in the order of appearance
This is a static initialization block. Here is Oracle Java SE documentation static initialization blocks.
In your example, int a is a local variable to the static initialization block. Here is another Stackoverflow post regarding local variables in static initialization blocks: What is the scope of variables declared inside a static block in java?. That is why you cannot access it in your main method.
That definition is a static initializer block. It allows extra logic for initialization, in this case applied to static members.
You will be able to access whatever you initialize in the block if you call the class A constructor, because "the Java complier copies initializer blocks into every constructor". Check docs
This is the static initializer block.
The reason that int a and class B cannot be accessed outside of the block is due to scoping. Similar to constructors and methods, variables declared within the scope of the initializer block are not accessible outside of the block.
Take a look at a test case :
public class StaticFieldTest {
public static int A= 1;
static {
A=2;
NAME="AAA";
// System.out.println(NAME); // Can't forward reference
}
public static String NAME = "Archer";
public static void main(String[] args) {
System.out.println(NAME);
}
}
The output is Archer.
It is obvious that NAME="AAA" is tedious. Why Java allow this sort of writing?
They Java Language Specification suggests that this is in place "to catch, at compile time, circular or otherwise malformed initializations."
The reason why your NAME = AAA; is compilable is that NAME is on the left hand side of the statement.
8.3.2.3. Restrictions on the use of Fields during Initialization
The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
The usage is not on the left hand side of an assignment.
The usage is via a simple name.
C is the innermost class or interface enclosing the usage.
You have to understand the order of initialization
The static initializers and class variable initializers are executed in textual order. In your example, static block precedes static variable assignment. If the order is switched, the answer will be different.
When a class is instantiated (object is created), Instance Variables are initialized and then Contructor is called.