2015-01-27 11 views
8

Warum nach dem eine Nullpointer werfen? :Nullpointer in Verfahren Rückkehr Typ Object

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : null; 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

Ich weiß, wenn ich eine der folgenden Bedingungen den Code tun wird keine Nullpointer werfen:

A)

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : (Object) null; 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

B)

public static Object myTest() { 
    Boolean x = false; 
    Boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : null; 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

Auch wenn ich den Kabeljau ändere e vollständig und Sie wie folgt funktioniert:

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 

    if(x && y) { 
     return new Object(); 
    } else if(x) { 
     return x; 
    } else if(y) { 
     return y; 
    } else { 
     return null; 
    } 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

Ich denke, der Compiler eine Art von einer Optimierung tut und irgendwie Dinge vermasselt? Ich nehme an, es so etwas wie ein Casting Problem, aber warum sollte es eine Nullpointer in diesem Fall statt einer Classcast werfen? Jede Information darüber, warum dies geschieht, würde sehr geschätzt werden!

Vielen Dank im Voraus

+0

Es wirft ein NullPointerException, weil irgendwo ein Null-Zeiger in diesem gottverdammten Durcheinander ist –

+0

Das dachte ich anfangs, aber ich denke, es lohnt sich zu betrachten, also +1 – Bathsheba

+0

@laune, es wirft eine "NullPointerException". –

Antwort

6

Wenn Sie einige Klammer zur besseren Lesbarkeit hinzufügen:

return (x && y) ? (new Object()) : (x ? x : (y ? y : null)); 

Sie, dass bei y ? y : null sehen können, wird der Compiler null (so dass die Typen übereinstimmen) unbox versuchen, eine Verursachung NPE geworfen werden.

+2

abzuschließen: Der Typ von 'y: null' wird durch' y' gesetzt, weil der linke Operand null ist. Wenn Sie '(Object) null 'hinzufügen, legen Sie den Typ fest und verhindern so das automatische Boolesche' boolean'. Wenn Sie 'Boolean y' hinzufügen, wird das Unboxing nicht benötigt, weil' null' in den 'Boole'-Typ passt. – njzk2

+2

nach dem Test passiert die NPE anscheinend bei '(x? X: ...)', weil der Compiler denkt, dass das Ergebnis von '(y? Y: null)' ein 'boolean' sein muss – njzk2

+1

@ njzk2 Dies kann http sein : //stackoverflow.com/questions/3882095/Boolean-conditional-operators-and-autoboxing, wenn wir '(y? y: null)' als äquivalent zu 'returnNull()' behandeln (aber ich habe es noch nicht gelesen damit ich falsch liegen kann). – Pshemo

1

(dieser Code ist unlesbar und sollte wahrscheinlich vermieden werden.), Aber tatsächlich zu antworten: Wie oben, hat die Argumentation mit Autoboxing und Unboxing zu tun und der Compiler macht Kontrollen. Es ist, als ob Sie boolean b = (Boolean) null geschrieben hätten, was zur Laufzeit eine NPE werfen würde.

In Beispiel A, werfen Sie es auf ein Objekt explizit, so gibt es kein Autoboxing hinzugefügt.

In Beispiel B, alles ist ein Objekt bereits (boolean ist ein primitiver, während Boolean ein Objekt ist), also wieder, keine Boxen oder Unboxing.

schließlich in Beispiel C gibt es kein Unboxing überhaupt, und stattdessen wird das Ergebnis nur geboxt, wenn es zurückgegeben wird. (if-else branching erlaubt es dem Compiler, jeden Zweig einzeln zu prüfen, anstatt ternäre Operatoren, die es erfordern, die Gesamtheit der Anweisung herauszufinden und dann der ganzen Anweisung einen Typ zuzuweisen. Das hat mit Aussagen gegen Ausdrücke und einer ganzen Menge Seltsamkeit zu tun in den Java Autoboxing und Typ-Prüfregeln)

(Casting Probleme bei der Kompilierung-Zeit passieren, wenn Sie eine inkompatible Guss wie versuchen. (Boolean) 7 oder zur Laufzeit, wenn Sie etwas tun:

int c = 7; 
Object co = (Object) c; 
Boolean bco = (Boolean) co; 
Verwandte Themen