Static block and main method behavior in java post java 5 - java

The question is around the usage of the static block around different version of Java
Upto JDK1.6:-
JVM first loads the class and while doing so (loading the class), code inside the static block gets executed. Later, JVM checks whether main method is there and then it executes.
However
JDK1.7 onwards :
JVM first checks the main method whether it is available or not.
if available
then JVM first execute static method (code inside)and
then main method will be executed.
if not available
throw error
Also, there is a usage of static block - while performing look up in enum but on the contrary there is no main method inside enum, so in what context does the above rule (dependency of main and static) apply?

Related

Non-Static initializer blocks - do I have a bit more control?

I am still on a learning curve in Java. To understand a bit more of initializer blocks I created a small test class:
public class Script {
{
Gadgets.log("anonymous 1");
}
public Script() {
Gadgets.log("constructor");
}
{
Gadgets.log("anonymous 2");
}
}
When I create an instance, I get this log:
Script: anonymous 1
Script: anonymous 2
Script: constructor
This tells me, both initializer blocks run BEFORE the constructor, in the order they appear in the source code (same as static initializers).
What I want to know is: Do I have a little more control over this behavior?
Because Java Documentation says (source):
Initializer blocks for instance variables look just like static
initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
The Java compiler copies initializer blocks into every constructor. Therefore,
this approach can be used to share a block of code between multiple
constructors.
So what exactly does "copies initializer blocks into every constructor" mean? According to my log, it seems, they are copied at the beginning of each constructor. Is this right?
Sharing such blocks between multiple constructors would also make perfectly sense, if they were copied to the END of each constructor (that's what I expected in my anonymous 2).
Is there a way to control those blocks a bit more or is my only option the "classic" way of writing a named method that gets called in every constructor if I want to do common tasks at the end of each constructor?
A constructor executes in the following order:
super() call, implicit or explicit.
Variable initializers and initializer blocks, in the order they appear in the source code.
Remainder of the constructor.
This is specified in the JLS and cannot be altered.
If a this() call is present it replaces (1) and (2).

Why use main() when you can use static{}?

What makes public static void main(String args[]) {} be the convention to test code instead of simply static {}?
class Test {
public static void main(String args[]) {
System.out.println("testing");
}
}
It seemingly has the same capabilities, you can instantiate owner class, use its methods, another classes, even send output as well:
class Test {
static {
System.out.println("testing");
}
}
Is there a standard reason to not use the small static {} to run your average test? Can I take it just as my choice/preference safely?
In other words, I'd like to find a case where you put a code in one that you couldn't (or shouldn't) put in another, that it wouldn't run or give unexpected result, etc.
I'd say the most prominent reason not to use static {} for such things is that you have little control over when it runs. static {} blocks run "when the class is initialized", which means at least four (watch out for the Spanish inquisition) detrimental things for this purpose:
It does not necessarily happen just because the class is loaded.
It does, on the other hand, happen just because you want an instance of the class or reference a static field from some other class, which is the main reason why you don't really want to put code with wide-ranging side-effects in static {} blocks.
It is also not guaranteed to not happen for such simple reasons as the Jar file being on your classpath. JVMs are free to run static {} blocks whenever they feel like it, as long as it is before any static references from the class from other code is made. "Before" could mean "at VM startup".
No VM implementation has any invocation arguments to run such code for you on request.
The purpose of static {} blocks is to initialize static class data (in possibly quite complex ways, of course), and from the preceding points you may be able to see why it's not particularly useful for anything else.
In java every application requires a main method which will be the entry point of the application. The main method required has the signature as follows:
public static void main(String[] args)
The difference between this method and the other one you suggested (besides the fact that your application needs a main method with this signature as an entry point) is that this is a method and takes the "String[] args" parameter. This parameter is where your arguments would go when running a program from the console.
Every java application can be run from the console and therefore it makes sense for every application to have a standard entry point method which will be able to take any special arguments.
Your static {} block is not necessarily a method or a function that can be called and therefore it can not be used as a entry point into your application. It takes no parameters and you have no control over when its code block will be run.

Order of static initialization blocks

I found a lot of posts on static initialization blocks, however I'm trying to get a little better picture about the execution order and the reason for it. The code below prints out the text in both the static blocks and "then" prints out the text in the main static block.
I understand the way the compiler calls this is to do all the static blocks in order when the class is loaded and then access the main method. But since the main method itself is static, why not execute that in order of the other static blocks (Not even sure if its useful, just trying to understand a concept and if there's a pressing reason for it being done this way). What if there's static block we want to run after the main block?
class Cat {
static
{
System.out.println("This block welcomes you first");
}
public static void main(String[] args)
{
System.out.println("Meow world ");
}
static
{
System.out.println("This block welcomes you after");
}
}
Actual Output
This block welcomes you first
This block welcomes you after
Meow world
Why not?
This block welcomes you first
Meow world
This block welcomes you after
Static initializers are executed as soon as the class is loaded. The main method is called after the class has been loaded.
This section of the JLS discusses the sequence of events (12.1.3-4):
12.1.3. Initialize Test: Execute Initializers
In our continuing example, the Java Virtual Machine is still trying to execute the method main of class Test. This is permitted only if the class has been initialized (§12.4.1).
Initialization consists of execution of any class variable initializers and static initializers of the class Test, in textual order. But before Test can be initialized, its direct superclass must be initialized, as well as the direct superclass of its direct superclass, and so on, recursively. In the simplest case, Test has Object as its implicit direct superclass; if class Object has not yet been initialized, then it must be initialized before Test is initialized. Class Object has no superclass, so the recursion terminates here.
12.1.4. Invoke Test.main
Finally, after completion of the initialization for class Test (during which other consequential loading, linking, and initializing may have occurred), the method main of Test is invoked.
The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code. And dont forget, this code will be executed when JVM loads the class. JVM combines all these blocks into one single static block and then executes. Here are a couple of points I like to mention:
If you have executable statements in the static block, JVM will automatically execute these statements when the class is loaded into JVM.
If you’re referring some static variables/methods from the static blocks, these statements will be executed after the class is loaded into JVM same as above i.e., now the static variables/methods referred and the static block both will be executed.
After that the main method will execute.
Thanks
Static initializers are executed as soon as the class is initialized (a class can be loaded and initialized at a later point of time. check Class.forName()). The main() method is called after the static initializers are executed. So the output is like that.

Print something using Static Block

I tried to print something using static block without Main method.
But how do I know at the time of the class loading static block will be
called.
Here removing main method its not printing anything in CMD as well as in Eclipse IDE.
Output :(with main method)
Static Block Called........
i :6
public class StaticBlock
{
static int i = 5;
static
{
System.out.println("Static Block Called........");
i ++;
}
public static void main(String args[])
{
System.out.println("i :"+i);
}
}
This is actually a behavioral detail which has changed in Java 7.
Prior to Java 7, whatever class is passed to the JVM as the application entry point, that class is loaded, initialized, and then the main method is looked up. Even if there's no such method, the class initialization code will have run. That includes any static initializers.
As of Java 7, the class will be loaded, but will not be initialized prior to looking up the main method. The JVM will abort with an error if the method is not found, and initialization will never occur.
Class loading vs. initialization
For many purposes this is just a subtle difference, but you have actually hit one where it is crucial. As per Java Language / Java Virtual Machine specifications, there is a clear distinction between:
class loading: this happens at any time, and for any class, the specific JVM implementation sees fit. It means loading the binary contents of the .class file, parsing them, verifying the bytecode, building up the constant pool, and so on;
class initialization: this happens at a precisely specified point, which is when the class is referred to (explicitly or otherwise) for the first time during a JVM run. At this point all the class initializers run.
Your StaticBlock class will not be loaded unless it is not referred form somewhere. Having the main method causes your class to be loaded because jvm loads the class when you run it. As soon as you refer your StaticBlock class, anywhere in your project, be it the main method in the same class or the main method in a different class. That will cause the class to be loaded and as soon as class will be laoded, static block in that class will be executed.
By refer I mean either you create an instance of it or you use any public method or field of the class using hte class name i.e StaticBlock.filed or StaticBlock.method().
In short, a class static block is executed when the class gets loaded by a classloader.

Who calls the main function in java?

public static void main(String[] args)
{
boolean t=true;
System.out.println("Before return");
if(t) return;
System.out.println("not execute");
}
In the above code when the return is used then it should return to the function which calls the main function. Who exactly calls the main function?
The Java Virtual Machine.
Java classes are executed within a larger context (a particular JVM as others have noted). Below are some possibilities:
you run java -cp {classpath here} com.example.foo.SomeClass to explicitly select a class for the java application launcher to run
you run java -jar somejar.jar (the class in question will be selected in the .jar file's manifest)
you are working within Eclipse and use debug/run to execute a particular class's main() method.
In all cases the main() method is the canonical entry point to executing code given a particular class. From the docs on the java JVM:
DESCRIPTION
The java tool launches a Java application. It does this by starting a Java runtime environment, loading a specified class, and invoking that class's main method. The method declaration must look like the following:
public static void main(String args[])
The method must be declared public and static, it must not return any value, and it must accept a String array as a parameter. By default, the first non-option argument is the name of the class to be invoked. A fully-qualified class name should be used. If the -jar option is specified, the first non-option argument is the name of a JAR archive containing class and resource files for the application, with the startup class indicated by the Main-Class manifest header.
The Java runtime searches for the startup class, and other classes used, in three sets of locations: the bootstrap class path, the installed extensions, and the user class path.
Non-option arguments after the class name or JAR file name are passed to the main function.
The javaw command is identical to java, except that with javaw there is no associated console window. Use javaw when you don't want a command prompt window to appear. The javaw launcher will, however, display a dialog box with error information if a launch fails for some reason.
You state:
In the above code when the return is used then it should return to the function which calls the main function.
There may not be any other Java function (in fact there usually isn't) which calls the main() function. It's the convention for declaring a well-known entry point. If the JVM is launched to run your class's main() method, then when main() returns, the JVM exits, except in a few special cases, e.g. there are other non-daemon threads running or there is a shutdown hook.
Here's a nice example of invoking main() via JNI_CreateJavaVM.
See Running Java programs...
The JVM uses the main() as the starting point for a program just like the int main() in C++.
Agree with above statements as JVM calls the main method because it is the entry point to any class that has to be loaded in order to execute the class.
Jvm starts main thread to call main method.
Java main() method is invoked by : JVM (JAVA VIRTUAL MACHINE)

Categories