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).
Related
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).
public class DataFactory {
private static DataFactory ourInstance = new DataFactory();
static {
System.out.println("static initialize");
}
private DataFactory() {
System.out.println("constructor");
}
public static void doNothing() {
System.out.println("inside doNothing");
}
}
public class App {
public static void main(String[] args) {
System.out.println("main start");
DataFactory.doNothing();
}
And After I run it, here is the printed sequence:
main start
constructor
static initialize
inside doNothing
Why calling DataFactory.doNothing() will trigger Constructor?
and why constructor is running before the static initializer?
When the class is initialized, it'll execute all of the static {...} and static field initializers, in the order they appear in the code (see JLS 12.4.2, and in particular step 9 in the list of steps there). In your example, there are two such initializers:
private static DataFactory ourInstance = new DataFactory();
The static {...} block
So, the first one happens first. It instantiate an object and assigns its reference to ourInstance. To instantiate the object, it needs to call the constructor, which it does (as you saw).
When that's done, the static block is executed, which prints "static initialize."
At this point, the class is initialized, and the method doNothing can finally be invoked.
It's invoking the constructor because you are creating an instance of DataFactory inside the same DataFactory; so it needs to call the constructor once in order to be able to instantiate it. Comment or delete the private static DataFactory ourInstance = new DataFactory(); line and the constructor call is not going to happens.
A static initializer is executed right after the class is initialized.
Sorry to tell that Rod_Algonquin is incomplete and Machina too. The right answer is that:
"Static Initialization Blocks run when the class is first loaded"
So, you are correct to ask "why the constructor is run before static?!".
How can? And there is a rule for initialization blocks (statics and instance).
The order in which initialization blocks appear in a class matters.
Just swap the order of your static initialization block to the static instantiation to see what happen:
public class DataFactory {
static { //// SWAPPED HERE
System.out.println("static initialize");
}
///// SWAPPED HERE
private static DataFactory ourInstance = new DataFactory();
private DataFactory() {
System.out.println("constructor");
}
public static void doNothing() {
System.out.println("inside doNothing");
}
}
OUTPUT:
main start
static initialize
constructor
inside doNothing
Your static field initialization calls the constructor.
In the end, the code that initializes the field "ourInstance" is also part of the static initializer.
So what is actually happening is:
public class DataFactory {
private static DataFactory ourInstance;
static {
outInstance = new DataFactory(); // 2
System.out.println("static initialize"); // 4
}
private DataFactory() {
System.out.println("constructor"); // 3
}
public static void doNothing() {
System.out.println("inside doNothing"); // 6
}
}
public class App {
public static void main(String[] args) {
System.out.println("main start"); // 0
DataFactory.doNothing(); // 1 (static init) and 5 (method call)
}
}
Here is the JLS documentation for the constructor:
Constructors are invoked by class instance creation expressions (§15.9)
And the JLS documentation for the static block:
A static initializer declared in a class is executed when the class is initialized (§12.4.2).
As you can see the constructor is first called when the class is initialized and then right after the constructor call then the static block is then called.
we know that a static block in java is resovled while compliling, not at runtime. Hence again We know that a static inner class is instantiated during the first call to the nested class.
Now suppose the nested class is having a static block. So, in that case can we say that static block inside the nested class will be resolved when the first attempt to access that nested class is made?
Sample code:
public class A
{
public static class B
{
static A a;
static
{
a=new A();
}
public static A getA()
{
return a;
}
}
}
Now I am accessing as:
A a= A.b.getInstance();
I hope at that point only static block in B will be executed and not before that.
This should answer your question:
public class Test {
public Test() {
System.out.println("Test instantiated");
}
public static class Inner {
static {
System.out.println("Static block executed");
}
public Inner() {
System.out.println("Test.Inner instantiated");
}
}
}
When calling:
Test test = new Test();
Test.Inner inner = new Test.Inner();
We get:
Test instantiated
Static block executed
Test.Inner instantiated
static block in java is resovled while compliling
No it isn't.
All static code is resolved once by the classloader, when loaded/initalized.
From jls Compile time error will happen from static blocks only when
If a static initializer cannot complete normally.
If a return statement appears anywhere within a static initializer.
If the keyword this or the keyword super or any type variable declared outside the static initializer, appears anywhere within a static initializer.
static block will be executed when the class is initialized, so in your example, the static block inside your static class B will get executed first.
I'm unsure what this does, I haven't seen it before and can't find any information about it.
private static String[] names = { "A.ttf" };
private static Map<String, Font> cache = new ConcurrentHashMap<String, Font>(names.length);
static {
for (String name : names) {
cache.put(name, getFont(name));
}
}
That is not a static method but a static block.
Static blocks are executed first(in same order they are declared) when class gets loaded and usually used for initializing things.
in your case it puts all names in "names" to cache.
refer this or an answer on SO for more info
A block is denoted by {\\some code}. A placed static keyword denotes that it is a static block. static block is known as Static Initializers and non static block is known as Instance Initializers.
None of them can contain return statement.
The non-static block will be called every time you are creating a new instance and it will be called/executed just before the Constructor. The static block will be called/executed only once and it will be the first time your are accessing the class.
Example:
class A {
static{ // static
System.out.println("Static block of Class A");
}
{ // non-static
System.out.println("Non-Static block of a instance of Class A");
}
public A(){
System.out.println("Constructing object of type A");
}
}
public class StaticTest {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
Output:
static block of Class A
Non-Static block of a instance of Class A
Constructing object of type A
Non-Static block of a instance of Class A
Constructing object of type A
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 ...