Exactly at what time static block or method is invoked [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Below is a program in which there are two static block which in my opinion should be called at first notice but in order from top to bottom but that does not happen
public class StaticTest {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
B b1 = new B();
}
}
class A {
static {
System.out.println("Static block of Class A");
}
{
System.out.println("Non-Static block of a instance of Class A");
}
public A() {
System.out.println("Constructing object of type A");
}
}
class B {
static {
System.out.println("Static block of Class B");
}
{
System.out.println("Non-Static block of a instance of Class B");
}
public B() {
System.out.println("Constructing object of type A");
}
}

"Exactly at what time static block or method is invoked" - For question like this, the Java Language Specification has the answer for you.
Static initializer:
A static initializer declared in a class is executed when the class is
initialized. Together with any field initializers for class
variables, static initializers may be used to initialize the
class variables of the class.
By running your code, you can easily figure out what runs first.

The static block in class B is not executed until B is actually needed. This is only the case in the 3rd statement of the main method. In fact, if you replace that line with
if (2*2 == 5) new B();
you'll notice that the static block of B is never executed, because B will not even be loaded.
To trace class loading, use the -verbose:class option of the java command.

This is the output of your test
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
Static block of Class B
Non-Static block of a instance of Class B
Constructing object of type A
I guss you are surprised why Static block of Class A is printed only once. This is because the static block runs only once on class loading. After you called new A()
JVM loaded A.class and when you called new A() again there was no need to load it again

The static blocks are executed when the respective classes are initialized.
The order of class initialization is determined by a combination of the static and dynamic dependencies between the classes involved; see When does static class initialization happen?
However, the JLS is effectively providing a set of constraints (this occurs before that) for which there are often many solutions. And this is an example where two "solutions" to the constraints are possible.
The class A is initialized before the new A() expression constructs an A
The class B is initialized before the new B() expression constructs an B
As you can see, initialize class A before B and B before A are both solutions.
In a situation like this, the actual order of initialization is not specified, and is likely to be JVM and/or bytecode compiler dependent ... and should not be relied upon.
It is also possible to construct a scenario in which there is a cycle in the dependencies, which results in there being no order that satisfies the constraints. In this case, the order is also indeterminate, and one of the classes may observe the other class in an uninitialized state. (Neither the compiler or the runtime flags this as an error!) This is described in JLS section 8.3.2.3.
Fortunately, this situation is pretty unusual.
Instance blocks and static methods are much simpler:
The instance blocks of a class are executed in program order each time an instance is created. They are executed in order between a constructor's super(...) "call" and the next line of that constructor. (The same applies when the constructor is the default constructor and/or the super() call is implicit.)
A static method is executed when it is explicitly called.

following is the output of your program
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
Static block of Class B
Non-Static block of a instance of Class B
Constructing object of type A
Static block is called only once when first time class object is created

Related

Static block not executed without initialization

I have a question regarding static blocks:
Let's say i've got a class looking like this:
class SomeClass {
static {
System.out.println("static block");
}
}
and I define a variable of type SomeClass somewhere.
public static void main(String args[]) {
SomeClass foo;
}
Now i thought the static block would have been executed but it wasn't. As far as i know the static block is executed as soon as the classloader loads the SomeClass class. Now to my real question:
Isn't the class loaded as soon as I define a variable of that type?. If yes why isn't the static block executed?
If the answer should be no, then how can i know if a class has already been loaded by the class loader and what are the different possibilities to have the class loaded (I know of 2: initializing the variable & using a static field/method)
Refer to this doc: http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html
So when are classes loaded? There are exactly two cases: when the new bytecode is executed (for example, FooClass f = new FooClass();) and when the bytecodes make a static reference to a class (for example, System.out).
In your example, SomeClass foo; does neither execute the bytecode of SomeClass nor make a static reference to SomeClass. That's why the class is not loaded.
So following your example, add a static field in the class
public class SomeClass {
static {
System.out.println("static block");
}
static String abc = "abc";
}
SomeClass is loaded in either:
SomeClass foo = new SomeClass();
Or
System.out.println(SomeClass.abc);
Isn't the class loaded as soon as I define a variable of that type?.
Yes, it is loaded1, but it won't be initialized as a result of declaring a variable. However, when you create an instance of that type, or access a static field of that type, that is sufficient to trigger initialization, including the execution of static blocks.
See this related Q&A - When does static class initialization happen? - which lists all of the things that can trigger initialization.
How can i know if a class has already been loaded by the class loader and what are the different possibilities to have the class loaded (I know of 2: initializing the variable & using a static field/method)
The only ways I can think of for finding out when a class is loaded (as distinct from initialized) are:
turning on the JVM's class loader messages (using -verbose:class), or
using a customer classloader that notices, and does something appropriate when it sees a request to load the class.
A class is actually going to be loaded:
when it is explicitly loaded using Class.forName or similar, or a direct call to a classloader,
when it is necessary to load it in order to link another class, or
at JVM launch time, if the class is named as the entry point class.
The loading / linking / initializing steps are specified in Chapter 12 of the JLS.
1 - In fact, SomeClass needs to be loaded at the same time that the class containing that main method is linked; i.e. before the method containing that local declaration is called.

Statement surrounded by static { ... statement; } why, what for? [duplicate]

This question already has answers here:
What is the difference between a static and a non-static initialization code block
(9 answers)
Closed 8 years ago.
I was looking over some code the other day and I came across:
static {
...
}
Coming from C++, I had no idea why that was there. Its not an error because the code compiled fine. What is this "static" block of code?
It's a static initializer. It's executed when the class is loaded (or initialized, to be precise, but you usually don't notice the difference).
It can be thought of as a "class constructor".
Note that there are also instance initializers, which look the same, except that they don't have the static keyword. Those are run in addition to the code in the constructor when a new instance of the object is created.
It is a static initializer. It's executed when the class is loaded and a good place to put initialization of static variables.
From http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html
A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.
If you have a class with a static look-up map it could look like this
class MyClass {
static Map<Double, String> labels;
static {
labels = new HashMap<Double, String>();
labels.put(5.5, "five and a half");
labels.put(7.1, "seven point 1");
}
//...
}
It's useful since the above static field could not have been initialized using labels = .... It needs to call the put-method somehow.
It's a block of code which is executed when the class gets loaded by a classloader. It is meant to do initialization of static members of the class.
It is also possible to write non-static initializers, which look even stranger:
public class Foo {
{
// This code will be executed before every constructor
// but after the call to super()
}
Foo() {
}
}
Static block can be used to show that a program can run without main function also.
//static block
//static block is used to initlize static data member of the clas at the time of clas loading
//static block is exeuted before the main
class B
{
static
{
System.out.println("Welcome to Java");
System.exit(0);
}
}
A static block executes once in the life cycle of any program,
another property of static block is that it executes before the main method.
Static blocks are used for initializaing the code and will be executed when JVM loads the class.Refer to the below link which gives the detailed explanation.
http://www.jusfortechies.com/java/core-java/static-blocks.php
yes, static block is used for initialize the code and it will load at the time JVM start for execution.
static block is used in previous versions of java but in latest version it doesn't work.

Static Initializers vs Instance Initializers vs Constructors [duplicate]

This question already has answers here:
Use of Initializers vs Constructors in Java
(10 answers)
Closed 8 years ago.
I am studying for an exam about Java. While I was studying, I have encountered syntaxes in java which are unfamiliar to me. Such as a curly braces({}) unside a class body without a name, some has a static keyword. I have found out that they are called "Initializers". Can anyone help me point out key differences among them and how they differ from a Constructor. Thanks
The main difference between them is the order they are executed. To illustrate, I will explain them with an example:
public class SomeTest {
static int staticVariable;
int instanceVariable;
// Static initialization block:
static {
System.out.println("Static initialization.");
staticVariable = 5;
}
// Instance initialization block:
{
System.out.println("Instance initialization.");
instanceVariable = 10;
}
// Constructor
public SomeTest() {
System.out.println("Constructor executed.");
}
public static void main(String[] args) {
new SomeTest();
new SomeTest();
}
}
The output will be:
Static initalization.
Instance initialization.
Constructor executed.
Instance initialization.
Constructor executed.
Briefly talking:
Static initialization blocks run once the class is loaded by the JVM.
Instance initialization blocks run before the constructor each time you instantiate an object.
Constructor (obviously) run each time you instantiate an object.
A Constructor is called once when a new instance of a class is created. The values initialized in the constructor belong to the scope of the instance. Each Instance may have a different value for the same field initialized in the Constructor.
Static Initializers are useful for executing setup code in Static Classes and filling out data structures in Enums. They are called once, in order from top to bottom when the Class is loaded into the JVM and the data exists within the scope of the Class or Enum. All references to the Class will return the same value for fields initialized in the Static Initializers
Unnamed Curly Braces are Anonymous code blocks that scope reference names. If you create a reference inside the blocks, you can not get the value of that reference outside the block. If you find yourself needing them it's a sign you need to refactor your code into more methods.
This is the kind of thing you really need to look in your textbook to get an answer. However I can give you some pointers. Its been some years since I programmed Java, so any information I gave you is general.
Generally a nameless block with curly braces is an anonymous function. Static initializers initialize data that is global to all instances of that class, and runs once the first time the class is referenced. You need to be careful about how you use static properties or methods. With this information you can find accurate details in your text books.

Anonymous code block in anonymous class Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is Double Brace initialization in Java?
While looking at some legacy code I came across something very confusing:
public class A{
public A(){
//constructor
}
public void foo(){
//implementation ommitted
}
}
public class B{
public void bar(){
A a = new A(){
{ foo(); }
}
}
}
After running the code in debug mode I found that the anonymous block { foo() } is called after the constructor A() is called. How is the above functionally different from doing:
public void bar(){
A a = new A();
a.foo();
}
? I would think they are functionally equivalent, and would think the latter way is the better/cleaner way of writing code.
{ foo(); }
is called instance initializer.
why?
As per java tutorial
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
"Instance initializers are a useful alternative to instance variable initializers whenever: (1) initializer code must catch exceptions, or (2) perform fancy calculations that can't be expressed with an instance variable initializer. You could, of course, always write such code in constructors. But in a class that had multiple constructors, you would have to repeat the code in each constructor. With an instance initializer, you can just write the code once, and it will be executed no matter what constructor is used to create the object. Instance initializers are also useful in anonymous inner classes, which can't declare any constructors at all."Source
This was also quoted in this answer.
Unless the runtime class of the object is accessed (by means of calling getClass()) and needs to be different from A for some reason (for instance because it serves as super type token), there is indeed no difference, and simply invoking foo() after construction would indeed be the more common idiom.

How do you disable lazy class loading/initialization in Sun's JVM?

By default, Sun's JVM both lazily loads classes and lazily initializes (i.e. calls their <clinit> methods) them. Consider the following class, ClinitBomb, which throws an Exception during a static{} block.
public class ClinitBomb {
static {
explode();
}
private static void explode() {
throw new RuntimeException("boom!");
}
}
Now, consider how to trigger the bomb:
public class Main {
public static void main(String[] args) {
System.out.println("A");
try {
Class.forName("ClinitBomb");
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("B");
ClinitBomb o2 = new ClinitBomb();
System.out.println("C");
}
}
We're guaranteed the explosion happens before point B, since forName's documentation says so; the question is whether it happens before point A (when Main is loaded.) In Sun's JVM, even though main() contains a static reference to ClinitBomb, it happens after A.
I want a way to tell the JVM to load and initialize ClinitBomb as soon as it initializes Main (so the bomb explodes before point A.) In general, I want a way to say, "whenever loading/initializing class X, also do so for any classes Y it references."
Is there a way to do that?
There is no way to do this. The JLS says, in §12.4.1 When Initialization Occurs (emphasis mine):
Initialization of a class consists of executing its static initializers and the initializers for static fields declared in the class. [...]
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.
T is a class and 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).
T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.
A Java implementation which initialized classes as soon as they were loaded would violate the JLS.
Although what you could do would be to use the JVM instrumentation API to write a ClassFileTransformer which added a static block to every class which explicitly initialized its referenced classes (via Class.forName, probably). As soon as one class gets initialized, all the classes reachable from it will be initialized. That might give you the result you're after. It's quite a lot of work, though!
Class.forName("...", true /*initialize*/, getClassLoader());
You were halfways there.

Categories

Resources