1

Possible Duplicate:
Java conditional operator ?: result type
NullPointerException through auto-boxing-behavior of Java ternary operator

Say I have two functions:

f(MyObject o) { ... }
f(int i) { ... }

And I call them like this:

f(someCondition ? 10 : null);

This compiles, but when I run it I get a null pointer exception (sorry I'm not sure on which condition). Some my questions are:

  1. Why does it even compile? What is the type of foo ? 10 : null?
  2. It clearly doesn't call the "correct" functions because that wouldn't cause an NPE. So which function is it calling? Does it do f((MyObject)10); or f((int)null)?
Community
  • 1
  • 1
Timmmm
  • 88,195
  • 71
  • 364
  • 509

2 Answers2

2
  1. The type is Integer - an auto boxing is done to the 10.
  2. f(int) is called, because it is the only accepted cast from Integer available (assuming no other overloads)
    When you try to cast a null to an int - you get your NPE.

2. f(Object) is called since Integer is an Object. This is called reference type widening
(sorry for the initial mistake, read it as f(Object))

amit
  • 175,853
  • 27
  • 231
  • 333
2

First of all, the problem doesn't have anything to do with the fact that you have overloaded versions of f. If you only have the version of f that takes an int, you get the same problem.

The thing is that both possible results of the ternary expression (before and after the :) must have the same type, because the whole expression condition ? expr1 : expr2 must have a single type. You can't have this expression evaluate to one type of condition is true, and another type if it is false.

So, the Java compiler is going to see if it can convert expr1 and expr2 to a single type. Note that int cannot be null (because it's a primitive type). However, 10 can be converted to Integer via autoboxing, and an Integer can also be null. So the type of the whole ternary expression is determined to be of type Integer. The result is either an Integer that contains the value 10 or an Integer that is null.

Step two is that you pass this Integer to f. Because f takes an int, it is auto-unboxed.

If you auto-unbox an Integer that is null, you get a NullPointerException - that's what happens here.

Jesper
  • 202,709
  • 46
  • 318
  • 350