JDK-6777143 : NullPointerException occured at conditional operator
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u10
  • Priority: P4
  • Status: Closed
  • Resolution: Future Project
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-11-26
  • Updated: 2010-12-07
  • Resolved: 2010-07-29
Description
FULL PRODUCT VERSION :
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
When i execute following code i get a NullPointerException.

import java.util.*;

public class Main {
  public static void main(String[] args) throws Exception {

    Object hashInputRule = new Object();
    Byte l = null;
    Byte rule = ((hashInputRule == null) ? ((byte) 0) : l);
  }
}

If change this line
    Byte rule = ((hashInputRule == null) ? ((byte) 0) : l);
to
    Byte rule = ((hashInputRule == null) ? ((byte) 0) : null);

NPE doesn't apper.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
D:\temp\java_bug>java -version
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)

D:\temp\java_bug>javac Main.java


D:\temp\java_bug>java Main
Exception in thread "main" java.lang.NullPointerException
        at Main.main(Main.java:8)

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect that NPE doesn't apper.
ACTUAL -
Actually i get NPE.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.NullPointerException
        at Main.main(Main.java:8)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.util.*;

public class Main {
  public static void main(String[] args) throws Exception {

    Object hashInputRule = new Object();
    Byte l = null;
    Byte rule = ((hashInputRule == null) ? ((byte) 0) : l);
  }
}
---------- END SOURCE ----------

Comments
EVALUATION I think that the fact that 15.25 defaults on numeric promotion can be regarded as a JLS bug: what's the point in accepting byte b1 = 0; static final int b2 = 1; byte b3 = true ? b1 : b2; but not the following? byte b1 = 0; byte b2 = 1; byte b3 = true ? b1 : b2; I think this is counterintuitive (at best) and should be fixed.
13-03-2009

EVALUATION It is because of NPEs that JLS 15.25 says "Note that binary numeric promotion performs unboxing conversion". The potential for NullPointerExceptions and OutOfMemoryErrors in 1.5 where they could never have occurred in 1.4 was well known to the JSR 201 Expert Group. It could have made unboxing conversion from the null type infer the target type from the context (and have the unboxed value be the default value for that type), but inference was not common before 1.5 expanded the type system and it's certainly not going to happen now. To be fully correct, the type of the ?: operator in the first example is the result of applying binary numeric promotion to (byte, Byte), which is int. A conversion from int to Byte is actually not permitted by JLS 5.2, any more than this is: int x = 1; Byte b1 = x; // Error byte b2 = x; // Error So a compile-time error should be given for the first example, making the potential NPE harmless. (The only way to keep the code compiling is to change binary numeric promotion so that promote(byte,Byte) is byte (then assignment conversion will box byte to Byte). This is a non-trivial change: promote(short,Short) is obviously short, but promote(short,byte) will have to take the lub, and then the interplay with ?:'s use of lub would need to be examined, to say nothing of the use of BNP by many other kinds of expression.)
02-12-2008

EVALUATION The submitter is complaining because the following code: Byte l = null; Byte rule = ((hashInputRule == null) ? ((byte) 0) : l); throws a NPE, while the following: Byte l = null; Byte rule = ((hashInputRule == null) ? ((byte) 0) : null); doesn't. However this is quite understandable - in the first case the types of the ternary operator are (byte, Byte) -> Byte, while in the later the types are (byte, <nulltype>)-> Byte. After reading JLS 15.25 (conditional operator) it seems that in the first case numeric promotion should be applied to both 2nd and 3rd operands of the conditional expression which, in turn, results in a unboxing op (the one throwing the NPE). In the second case, since one of the two operands is 'null' the 3rd bullet is applied, so that the conditional expression has the type of the non-null operand (byte in this case). Eclipse does the same thing. Could we do something to improve this?
27-11-2008