È dovuto a autoboxing e autounboxing. Se si guarda il bytecode (sotto), è possibile vedere le chiamate a Double.valueOf
(boxing il 3.7d
) e Double#doubleValue
(unboxing il risultato dell'espressione condizionale). Gli operandi per l'operatore condizionale devono essere dello stesso tipo, in modo che il compilatore è effettivamente trasformando il codice in questo modo:
public double getSomeDouble() {
return ("" != null ? Double.valueOf(3.7d) : null).doubleValue();
}
... perché Double
è il tipo comune più specifica si possono trovare per 3.7d
e null
.
ho usato un argomento stringa (per eliminare ottimizzazione del compilatore attorno all'espressione invariante "" != null
, che il compilatore in grado di dire non sarebbe mai stato vero):
public double getSomeDouble(String str) {
return str != null ? 3.7d : null;
}
che diventa efficace:
public double getSomeDouble(String str) {
return (str != null ? Double.valueOf(3.7d) : null).doubleValue();
}
... e in effetti ho ottenuto un NPE in fase di esecuzione quando sono passato in null
per str
, quando ha provato a chiamare doubleValue()
su null
.
Ecco il bytecode per il mio getSomeDouble(String)
(da javap -c MyClass
): [? Related]
public double getSomeDouble(java.lang.String);
Code:
0: aload_1
1: ifnull 13
4: ldc2_w #7 // double 3.7d
7: invokestatic #9 // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
10: goto 14
13: aconst_null
14: invokevirtual #10 // Method java/lang/Double.doubleValue:()D
17: dreturn
fonte
2015-04-14 09:55:52
(http://stackoverflow.com/q/8098953/1391249) – Tiny