【问题标题】:order of execution of static method静态方法的执行顺序
【发布时间】:2015-09-05 01:54:42
【问题描述】:
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)

【问题讨论】:

  • @kocko 因为这是他在...中调用方法的顺序
  • 在实例变量上调用静态方法是一种糟糕的编码风格。始终在类本身上调用静态方法:sample1.method1()
  • @Marvin:不同的问题。在那个问题中,写入了不同的流。
  • @EricJ.:OP 想知道他的“静态 hai”(写给 System.out)和他的堆栈跟踪(通常写给 System.err)的顺序。我不明白这是一个不同的问题。

标签: java static-methods


【解决方案1】:

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

如果你第二次调用它,顺序可能会改变。

【讨论】:

  • @Ramaiah.S 我写的是can 而不是must
【解决方案2】:

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/

【讨论】:

  • 这与所提出的问题有什么关系?
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    您遇到的问题是 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)
    

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

    将代码更改为:

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

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

    【讨论】:

    • 你也可以在抛出异常之前调用System.out.flush()来达到这个效果。
    • @Quincunx 假设您的终端仿真器没有进行其他缓冲和各种未知数 - 是的,应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2017-08-16
    相关资源
    最近更新 更多