静态方法的执行顺序

时间:2015-06-19 07:10:52

标签: java static-methods

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(); 
    }
}

,输出为:

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

static hai

为什么订单有变化?它应输出:

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

4 个答案:

答案 0 :(得分:16)

您遇到的问题是当您的代码打印到Exception时,System.err会打印到System.out

所以,如果没有一个命名不好的课程(PascalCase请),我们可以这样做:

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

我得到的输出是:

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)

所以他们实际上是交错的。即输出的顺序是未定义,因为有两个输出流被打印到控制台。

将代码更改为:

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

产生预期的结果。

你也可以捕捉异常并将其打印到System.out以达到同样的效果:

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。我相信你知道这一点,但是你永远不应该在static的实例上调用class方法。您应该始终在static本身上调用class方法。所以在你的例子中,你应该总是这样做:

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

答案 1 :(得分:5)

这是因为exception打印到STDERR,System.out.println()打印到STDOUT,两个流都不同步。

如果您第二次打电话,订单可以更改。

答案 2 :(得分:1)

这是因为out和err是两个不同的输出流。但是,它们都在控制台上打印。因此,您不会将它们视为不同的流。尝试以下代码并检查输出。

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

答案 3 :(得分:0)

在Java中只是一件好事:

在Java中有几种类型的init文件: 让我们看一个例子:

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

了解更多相关信息: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html 或者在这里:

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