I have following scenario
package com.example.test;
public class StaticTest {
public static final String STATIC_VAR="Static Var";
static{
System.out.println("Static Block Called....");
}
public static void init(){}
}
package com.example.test;
public class MainClass {
public static void main(String[] args) {
System.out.println("Test static initialization");
String staticvar =StaticTest.STATIC_VAR;
System.out.println("Referred static variable--> "+ staticvar);
System.out.println("Calling static method");
StaticTest.init();
System.out.println("Static method invoked");
}
}
The output I am getting is
Test static initialization
Referred static variable--> Static Var
Calling static method
**Static Block Called....**
Static method invoked
And output I was expecting was
Test static initialization
**Static Block Called....**
Referred static variable--> Static Var
Calling static method
Static method invoked
I was thinking that as soon as I refer static variable static block will get executed.
any explanation?
Because the variable is public static final it is being inlined by the compiler.
All references to it are being replaced by the actual value as it cannot change, this is known as a Compile Time Constant.
Your code is essentially being compiled to:
System.out.println("Test static initialization");
String staticvar = "Static Var";
If you assign the value to the return value of a method -
public static final String STATIC_VAR=getStaticVar();
private static String getStaticVar() {
return "Static Var";
}
You will get the result you expect.
There is a good SO answer the explains inlining and the guarantees given by the JLS on compile time constants.
String staticvar =StaticTest.STATIC_VAR;
does not load the class StaticTest. Instead, the compiler inlines the value of the constant into MainClass. So at runtime, this code will be executed:
String staticvar = "Static Var";
The JLS calls this a "constant":
A variable of primitive type or type String, that is final and
initialized with a compile-time constant expression (§15.28), is
called a constant variable.
which means that StaticTest.init(); is the first time when the VM has to actually load the class. This causes the execution of the static block.
The primary reason is that you declared STATIC_VAR as constant value, which will be inlined by the compiler instead of being referenced. Change the code to
public static /*final*/ String STATIC_VAR="Static Var";
and you will get the behaviour you expect.
See §12.4.1. When Initialization Occurs of the Java Language Specification:
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
...
A static field declared by T is used and the field is not a constant variable (§4.12.4).
See the other answers on inlining of constant values for the technical background.
Related
I have read at many places that static method can access static variables only but when I write code, I am mentioning my variables as static and my code still works.
Is anyone out there to help me understand this concept clearly?
public class LearnMain {
public static void main(String args[])
{
int a = 1;
System.out.println(""+a);
}
}
static method directly access static variable and static method bcz static method execute class name ,and static variable get memory and initialization when the class is loaded in JVM, when any variable initialization then we have call this variable but non-static method get memory when object is created. without object non static variable and non static method could't be execute.
As per java doc, static block is executed when the class is initialized.
Could anyone please tell me why static block is not executed when I run below code?
class A {
static {
System.out.println("Static Block");
}
}
public class Main {
public static void example1() {
Class<?> class1 = A.class;
System.out.println(class1);
}
public static void example2() {
try {
Class<?> class1 = Class.forName("ClassLoading_Interview_Example.ex1.A");
System.out.println(class1);
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
example1();
}
}
A class's static initialization normally happens immediately before
the first time one of the following events occur:
an instance of the class is created,
a static method of the class is invoked,
a static field of the class is assigned,
a non-constant static field is used, or [...]
You are currently not doing any of the above.
So, by replacing
Class<?> class1 = A.class;
System.out.println(class1);
with this for example
A object = new A();
will give you your result.
Referencing A.class will not resulting in executing A's static initializers, see here
Initialization of a class consists of executing its static
initializers and the initializers for static fields (class variables)
declared in the class.
And
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:
T is a class and an instance of T is created.
A static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant
variable (§4.12.4).
I have few question about static in java
Can we have static block in non static class??If an object of
that(no-static) class is initialized in some other class,will the
static block get executed then??
If there is a static class having static block and variable( int a =
3) and main() method,and it is executed then will the variable
initialization take place first or static block execution?I know
that static block gets executed before the main() method.
1) No, you cant, try this
class Test1 {
class X {
static { <-- compile error: Cannot define static initializer in inner type Test1.X
}
}
...
X should be static.
Note: I assume we are talking about nested classes, because this is where static modifier is applicable for classes
2) it depends, see this
class Test1 {
static {
x = 3;
}
static int x = 2;
public static void main(String[] args) throws Exception {
System.out.println(x);
}
}
output
2
but now
class Test1 {
static int x = 2;
static {
x = 3;
}
public static void main(String[] args) throws Exception {
System.out.println(x);
}
}
output will be
3
Static initialization runs only ones during class loading, it happens always before any instance instantiation. Interestingly both static fields initialization and static init block code runs in the same bytecode function with the name <clinit>:
static <clinit>()V
L0
LINENUMBER 12 L0
ICONST_3
PUTSTATIC test/Test1.x : I
L1
LINENUMBER 15 L1
ICONST_2
PUTSTATIC test/Test1.x : I
RETURN
Please look here http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
It's called static initializer in the spec. This code will be executed when JVM loads the class. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.
You can't use static code in nonstatic inner classes:
public class MyClass {
static {
System.out.println("static code from nonstatic class");
}
class In {
/* it will not compile
static {
}
*/
}
static class In2 {
static {
System.out.println("static code from static inner class");
}
}
public static void main(String[] args) {
MyClass c = new MyClass();
}
}
See Detailed Initialization Procedure in The Java® Language Specification for details about calling order. Simply the static blocks are executed in the order they appear in the source code.
Having a static class vs. a normal class does not affect what programming constructs you are allowed to use, but simply controls whether or not the class has access to instance fields/methods of the surrounding class.
Yes we can have a static block in a non-static class and it is loaded as soon as class loads in JVM
public class StaticDemo {
static{
System.out.println("already loaded");
}
public static void main(String [] args){
}
}
This outputs already loaded
For question 2, the answer can be found in the Java Language Specification §12.4.2, in particular step 9 of the "detailed initialization procedure":
Next, execute [...] the class variable initializers and static initializers of the class [...] in textual order, as though they were a single block.
In other words, the static {} blocks and the initializer expressions of static fields are executed in the order they appear in the source code - if the static block is before the field declaration then it will run first (and see the default value of the field, typically null or 0), if the static block is after the field declaration then it will run second (and will see the value assigned by the initializer expression).
I have the following class:
public abstract class A()
{
public static final SomeString = null;
static()
{
SomeString = "aaa";
}
}
When is this static method invoked and how?
What is the purpose in creating such a static method (without name / return type)?
That is not a method, it's a static initialization block, and your syntax is wrong
public abstract class A()
{
public static String SomeString = null;
static
{
SomeString = "aaa";
}
}
The easiest way of initializing fields (static or instance) in Java at the time of their declaration is simply by providing a compile time constant value of a compatible data type. For example:
public class InitializationWithConstants{
public static int staticIntField = 100;
private boolean instanceBoolField = true;
}
This type of initialization has its limitation due to its simplicity and it can not support initialization based even on some moderately complex logic - like initializing only selected elements of a complex array using some logic in a for loop.
Here comes the need for static initialization blocks and initializer blocks for initializing static and instance fields, respectively.
It's a normal block of code enclosed within a pair of braces and preceded by a 'static' keyword. These blocks can be anywhere in the class definition where we can have a field or a method. The Java runtime guarantees that all the static initialization blocks are called in the order in which they appear in the source code and this happens while loading of the class in the memory.
public class InitializationWithStaticInitBlock{
public static int staticIntField;
private boolean instanceBoolField = true;
static{
//compute the value of an int variable 'x'
staticIntField = x;
}
}
Since static initialization blocks are actually code-blocks so they will allow us to initialize even those static fields which require some logical processing to be done for them to get their initial values.
Your syntax is incorrect; it should be:
public abstract class A()
{
public static final String SomeString;
static
{
SomeString = "aaa";
}
}
The static block allows static variables to be initialised when the class is loaded when that initialisation is more complication than simply = something;.
Reference
Syntax aside, you're looking at a static initializer block. They're mentioned here.
Essentially, a static initializer block is a piece of code that executes when a class is loaded, and can be used to initialize static fields in the class.
Example:
public abstract class A
{
public static final String SomeString;
static
{
System.out.println("static{}");
SomeString = "aaa";
}
public static void main(String[]args)
{
System.out.println("main");
}
}
Output:
static{}
main
yeas it's not a method. it is static block and i'st evaluated once when the owner class is loaded.
u can use it for initialize static variable dynamically ...
public class test
{
private static int a;
public static void main(string[] args)
{
modify(a);
system.out.print(a);
}
public static void modify(int a)
{
a++;
}
}
i want to know how a private static variable is accessed directly in main() method.
although static variables can be accessed directly from static methods but the variable is private and method is main().. pls explain
Yes, it is static but since it is located in the same class as main method, it can be accessed by the static methods in the class (including main)... and actually also by normal methods in the same class
It doesn't bother you that modif() can access the attribute a ? Then it's the exact same thing with the main().
The only special thing about main() is the fact that this method is used as an entry point of your application. This particularity doesn't interfer with the fact that main() is static.
By the way, your modif() method doesn't really access the static a field because it's shadowed by the parameter a.
Another thing, a++ won't do anything because you're just modifying the value of the parameter a inside a method; int is a primitive and is passed by value, so your code won't change the value of a outside of the method scope.
I think you wanted something like this :
public class test{
private static int a;
public static void main(string[] args){
modify(); //<--- No parameters needed here !
system.out.print(a);
}
public static void modify(){ //<--- No parameters needed here !
a++;
}
}
If you declare a member variable as private, this means it can only be accessed from methods in the same class. Your main() method is actually a static method in the same class, so it can access any private variables.
Since main is in the same class you can access the private variable.
A private member variable is visible to any method of that class, static or not. There are restrictions on what static methods can do but those are separate from the visibility rules.
but
public class test
{
private int a;
public static void main(string[] args)
{
system.out.print(a);
}
}
you can't access a instance variable 'a' directly in main()... it will show error bcoz it is private...... but how it accesses private static...