JDK-8360162 : Compiler wrongly add an invokevirtual of *numeric*Value
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,25
  • Priority: P5
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2025-06-20
  • Updated: 2025-06-23
  • Resolved: 2025-06-20
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
OS: Microsoft Windows 11 Business / 10.0.26100 build 26100
Java runtime: 
openjdk version "21.0.7" 2025-04-15 LTS
OpenJDK Runtime Environment Microsoft-11369940 (build 21.0.7+6-LTS)
OpenJDK 64-Bit Server VM Microsoft-11369940 (build 21.0.7+6-LTS, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
Writing a method that safetly sums two Numerics (namely Double, Float, Integer and Long), using a ternary operator to return null in case of sum of two nulls, behaves unexpectedly, generating an NPE.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run and compile the given source code
javac SumUtils.java
java SumUtils

EXPECTED VS ACTUAL BEHAVIOR
EXPECTED -
null
ACTUAL -
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Double.doubleValue()" because "<parameter2>" is null
        at SumUtils.safeSum(SumUtils.java:9)
        at SumUtils.main(SumUtils.java:5)

---------- BEGIN SOURCE ----------
public class SumUtils {
  private SumUtils() {}
  
  public static void main(String... args) {
    System.out.println(safeSum(null, null));
  }

  static Double safeSum(Double a, Double b) {
    return a == null ? b
         : b == null ? a
         : a + b;
  }
}
---------- END SOURCE ----------


Comments
Or you can use: static Double safeSum(Double a, Double b) { return a == null ? b : b == null ? a : (Double) a + b; }
20-06-2025

Hi!, Thank you for submitting your report! It is a known issue reported multiple times, but it is not a bug. As developers mentioned in previous reports: This seems to be in accordance with The Java Language Specification (JLS): http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25 "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." The result of Ternary operator is Double, thus b has to be unboxed to get a primitive Double value. The second value is a null - so unboxing results in NullPointerException. I linked some related issues to this report, in case you might want to see the discussions about this topic. Thank you again for your report, It's very appreciated!
20-06-2025

Impact -> L (Known issue, not a bug) Likelihood -> H (Always occurs) Workaround -> L (Use if-else instead) Priority -> P5
20-06-2025

Using the if-else instead of the ternary operator works fine: static Double safeSum(Double a, Double b) { if(a==null){ return b; }else if(b == null){ return a; }else{ return a+b; } } or static Double safeSum(Double a, Double b) { if(a==null) return b; if(b == null) return a; return a+b; }
20-06-2025

The observations on macOs Sequoia 15.5: - JDK 8: Failed, Observed: Exception in thread "main" java.lang.NullPointerException at SumUtils.safeSum(SumUtils.java:9) at SumUtils.main(SumUtils.java:5) - JDK 25-ea+8-843: Failed, Observed: Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Double.doubleValue()" because "<parameter2>" is null at SumUtils.safeSum(SumUtils.java:9) at SumUtils.main(SumUtils.java:5)
20-06-2025