order of execution of static method

1k views Asked by At
public class Sample {

    public void method()
    {
        System.out.println("normal hai");   
    }
    public static void method1()
    {
        System.out.println("static hai");
    }
    public static void main(String[] args) {
        Sample s = null;
        s.method1();
        s.method(); 
    }
}

and the output is:

Exception in thread "main" java.lang.NullPointerException
        at com.csvfile.sample.main(Sample.java:22)

static hai

Why has the order changed? It should output:

static hai
Exception in thread "main" java.lang.NullPointerException
    at com.csvfile.sample1.main(Sample.java:22)
4

There are 4 answers

1
Jens On

That is because the exception is printed to STDERR and System.out.println() is printed to STDOUT and both streams are not synchronized.

If you call it a second time the order can change.

2
Boris the Spider On

The issue you have is that the Exception is printed to System.err while your code prints to System.out.

So, without a badly named class (PascalCase please) we can do:

public static void main(String[] args) throws Exception {
    final System system = null;
    system.out.println("Odd");
    System.out.println(system.toString());
}

And the output I get is:

Exception in thread "main" java.lang.NullPointerException
Odd
    at com.boris.testbench.App.main(App.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

So they're actually interleaved. i.e. the order of the output is undefined as there are two output streams being printed to the console.

Changing the code to:

public static void main(String[] args) throws Exception {
    final System system = null;
    system.err.println("Odd");
    System.err.println(system.toString());
}

Produces the desired result.

You could also catch the exception and print it to System.out to achieve the same effect:

public static void main(String[] args) throws Exception {
    final System system = null;
    system.out.println("Odd");
    try {
        System.out.println(system.toString());
    } catch (RuntimeException ex) {
        ex.printStackTrace(System.out);
    }
}

P.S. I'm sure you know this, but you should never call a static method on an instance of the class. You should always call the static method on the class itself. So in your example, you should always do:

public static void main(String[] args) {
    sample1 s = new sample1();
    s=null;
    sample1.method1();
    s.method(); 
}
0
Sujit Chaitanya On

This is because out and err are two different output streams. However, both of them print on console. So you do not see them as different streams. Try the below code and check output.

for (int i = 0; i < 10; i++) {
        System.out.println(i);
        System.err.println(i);
}
1
narancs On

Just a good to know thing in Java:

In Java there are several types of init fileds: let`s see an example:

public class HunarianEngineer{

static{
       System.out.println("1.This is a static block, called when the JVM pull in the class first time ever");
 }

{
 System.out.println("2.This is an instance block, runs before constructor");
}

public HungarianEngineer(){
     System.out.println("3.I`m a constructor");
}

}//EndOfClass

Read more about them: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html or here:

http://www.thejavageek.com/2013/07/21/initialization-blocks-constructors-and-their-order-of-execution/