Подтвердить что ты не робот

Порядок выполнения статического метода

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)
4b9b3361

Ответ 1

Проблема заключается в том, что 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. Я уверен, что вы это знаете, но вы никогда не должны вызывать метод static для экземпляра class. Вы всегда должны вызывать метод static для самого class. Поэтому в вашем примере вы всегда должны:

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

Ответ 2

Это потому, что exception печатается в STDERR, а System.out.println() печатается в STDOUT, и оба потока не синхронизируются.

Если вы вызываете его во второй раз, заказ может измениться.

Ответ 3

Это потому, что out и err - это два разных потока вывода. Однако, оба они печатают на консоли. Поэтому вы не видите их как разные потоки. Попробуйте приведенный ниже код и проверьте вывод.

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

Ответ 4

Просто хорошо знать вещь в 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/