JDK-7173476 : Ternary operator fails on valid statements due to unexpected type casting
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2012-06-01
  • Updated: 2025-06-20
  • Resolved: 2012-06-01
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows XP Tablet PC Edition 2005 SP3 (probably irrelevant)

EXTRA RELEVANT SYSTEM CONFIGURATION :
Using Eclipse 3.7.2 (probably irrelevant)

A DESCRIPTION OF THE PROBLEM :
The following code:

public static class Item {
  public Long getID() { return null; }
}

public static void main(String[] args) {
  Item i = new Item();
  Long ID = (i==null) ? 0L : i.getID();
  System.out.println(ID);
}

produces a java.lang.NullPointerException in the line starting with "Long ID = ...". This seems to be due to the fact that the ternary operation is trying to cast the null value returned from i.getID() to a long (lower case) to match the type of 0L rather than casting 0L to a Long. This, in my opinion, seems like a bug as the equivalent if...else statement does not show this behavior. This happens with Integer and Boolean as well. Switching the result cases (i!=null) does not fix the problem (i.e. first result case does not take type-precedence over second one).

Explicitly casting 0L to Long instead by changing the line to:

  Long ID = (i==null) ? (Long) 0L : i.getID();

fixes the problem.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run code:

public static class Item {
  public Long getID() { return null; }
}

public static void main(String[] args) {
  Item i = new Item();
  Long ID = (i==null) ? 0L : i.getID();
  System.out.println(ID);
}

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
assign null to ID and print it
ACTUAL -
throws java.lang.NullPointerException in line starting with "Long ID = ..."

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.NullPointerException at Main.main (line starting with "Long ID = ...")

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Main {

  public static class Item {
    public Long getID() { return null; }
  }

  public static void main(String[] args) {
    Item i = new Item();
    Long ID = (i==null) ? 0L : i.getID();
    System.out.println(ID);
  }

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Explicitly cast result cases to "broader" type:
  Long ID = (i==null) ? (Long) 0L : i.getID();

Comments
EVALUATION The described behavior is compatible with the one described in the JLS (section 15.25): "The type of a conditional expression is determined as follows: [...] If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (ยง5.1.7) to T, then the type of the conditional expression is T" This means that the type of the conditional expression is 'long' - hence the synthetic cast.
01-06-2012