2015-06-19 17 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(); 
    } 
} 

e l'uscita è:ordine di esecuzione delle metodo statico

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

static hai 

Perché ha cambiato l'ordine? Dovrebbe uscita:

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

@kocko Perché è l'ordine che ha chiamato i metodi in ... – immibis

+0

La chiamata di un metodo statico su una variabile di istanza è uno stile di codifica errato. Chiamate sempre metodi statici sulla classe stessa: 'sample1.method1()' –

+0

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

risposta

5

Questo è perché il exception è stampato su STDERR e System.out.println() è stampato su STDOUT e sia flussi non sono sincronizzati.

Se si chiama una seconda volta l'ordine può cambiare.

+0

no, non sta cambiando –

+10

@ Ramaiah.S ho scritto 'can' not' must' – Jens

16

Il problema è che il Exception viene stampato su System.err mentre il codice viene stampato su System.out.

Così, senza una classe di mal di nome (PascalCase per favore) che possiamo fare:

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

E l'uscita che ottengo è:

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) 

Quindi sono in realtà Interleaved. Ad esempio, l'ordine dell'uscita è non definito in quanto vi sono due flussi di output che vengono stampati sulla console.

Modifica del codice a:

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

produce il risultato desiderato.

Si potrebbe anche intercettare l'eccezione e stamparlo System.out per ottenere lo stesso effetto:

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. Sono certo che lo sai, ma non dovresti mai chiamare un metodo static su un'istanza di class. Dovresti sempre chiamare il metodo static sullo stesso class. Quindi, nel tuo esempio, dovresti sempre farlo:

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

Probabilmente potresti anche ottenere l'effetto chiamando 'System.out.flush()' prima di lanciare l'eccezione. – Justin

+0

@Quincunx supponendo che il tuo emulatore di terminale non faccia altro buffering e tutti i tipi di incognite - sì, dovrebbe funzionare. –

1

Questo perché out e err sono due diversi flussi di output. Tuttavia, entrambi stampano su console. Quindi non li vedi come flussi diversi. Prova il codice seguente e controlla l'output.

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

Solo un buon sapere cosa in Java:

In Java ci sono diversi tipi di Campi INIT: Let `s vedere un esempio:

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 

Per saperne di più su di loro: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html o qui:

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

+2

In che modo questo si riferisce in qualche modo alla domanda? –