What are the benefits of using a basic (...) static initializer as a pseudo entry point?
The entry point of a program in java is usually something like this
// MyMain.java
public class MyMain{
//whatever
public static void main(String args[]){
System.out.println("balderdash");
}
}
However, since there is basically only one SOP, the above class could be the same as
// MyMain.java
public class MyMain{
//whatever
static {
System.out.println("balderdash");
}
}
One obvious advantage of using main (...) is that arguments can be passed to the program. Another one (I assume here) may have to do with the garbage collector handling objects created in a static block differently.
What other benefits come from using a language-defined entry point - public static void main (String args []) instead of using a static initializer.
ps The above snippets are for illustration purposes only and may not compile
source to share
- You can test it or call it from other applications.
- This is what other people expect.
- If you are executing your entire application in the context of a static initializer, I suspect that you will effectively hold on to this type of lock all the time. If any other thread tries to call a static method in the same class, it will block. This problem occurs when you try to use a concept in unexpected ways - it is simply conceptually "wrong". Initializing a class is simply not the same as starting an application.
EDIT: Here's an example of this problem:
class SampleTask implements Runnable
{
public void run()
{
System.out.println("Calling someStaticMethod");
Test.someStaticMethod();
System.out.println("someStaticMethod returned");
}
}
public class Test
{
static
{
System.out.println("Starting new thread...");
new Thread(new SampleTask()).start();
System.out.println("Thread started. Sleeping");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted!");
}
System.out.println("Finished sleeping");
}
public static void someStaticMethod()
{
System.out.println("In someStaticMethod");
}
public static void main(String[] args)
{
System.out.println("In main. Sleeping again.");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted!");
}
}
}
Output:
Starting new thread...
Thread started. Sleeping
Calling someStaticMethod
Finished sleeping
In someStaticMethod
someStaticMethod returned
In main. Sleeping again.
Note how a call someStaticMethod
from a new thread must wait for the static initializer to complete before starting it.
source to share
The main reason why it is better to use main()
is because you can have multiple main methods in your application (in different classes). If you load a class, it main()
doesn't get executed automatically, and static
blocks of code are always executed exactly once when the first class is loaded, and there is no way to prevent this.
source to share
If you don't have an entry point, you can't start anything. If you have many entry points (many basic methods), the user who launches your application controls will run at the command line.
On the other hand, static initialization blocks are executed when the class is loaded. Controlling which class is loaded and the order in which classes are loaded (and the execution of their static initialization blocks) are much more difficult to control. This is a good enough reason not to put a lot of logic in static initialization blocks. You make something harder to read and understand, and in return you get something harder to use.
source to share