2015-06-19 5 views
13
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) 
+0

@kocko Потому что это порядок, который он назвал методами в ... – immibis

+0

Вызов статического метода для переменной экземпляра - это плохой стиль кодирования. Всегда вызывайте статические методы в самом классе: 'sample1.method1()' –

+0

http://stackoverflow.com/questions/1883321/java-system-out-println-and-system-err-println-out-of-order – Marvin

ответ

5

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

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

+0

nope это не меняется –

+10

@ Ramaiah.S Я написал его 'can' not' must' – Jens

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

Возможно, вы также можете добиться эффекта, вызвав 'System.out.flush()' перед тем, как выбросить исключение. – Justin

+0

@Quincunx предполагает, что ваш эмулятор терминала не выполняет некоторую другую буферизацию и всевозможные неизвестные - да, должно работать. –

1

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

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

Просто хорошо знать вещь в Java:

В Java существует несколько типов инициализации fileds: let`s см пример:

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/

+2

Как это может быть связано с вопросом? –