3

Why does the following Java code throw a NullPointerException?

public static void main(String[] args) {
    getInteger(null);
}

public static Integer getInteger(Number n) {
    return (n == null || n instanceof Integer) ? (Integer)n : n.intValue();
}

EDIT: I added parentheses to end the confusion about "whether I am sometimes returning a boolean".

Hans Brende
  • 7,847
  • 4
  • 37
  • 44
  • @TimBiegeleisen That's what I thought too. Test it yourself :) – Hans Brende Dec 03 '15 at 07:04
  • 1
    as a sidenode, `n instanceof Integer` will also fail if `n` is null, so you are basicly checking it twice. – SomeJavaGuy Dec 03 '15 at 07:09
  • if LHS condition made true then how RHS side goes compiter , if i am not wrong then LHS return true then it won't go to RHS, Question is very good, i appreciate, but i am looking that many answer came and also get upvote , but no body explaining my this query. can any one please and make me correct – Vishal Gajera Dec 03 '15 at 07:14
  • I think you just answered your own question. – Tim Biegeleisen Dec 03 '15 at 07:17
  • @TimBiegeleisen Nope. Try the code with parentheses. Still throws NullPointerException. – Hans Brende Dec 03 '15 at 07:19
  • 3
    @HansBrende change `n.intValue()` to `Integer.valueOf(n.intValue())` (all the current answers seem incorrect). – assylias Dec 03 '15 at 07:25
  • 1
    @assylias thank you for the only correct response! Java auto-unboxing at work... shoulda known. – Hans Brende Dec 03 '15 at 07:30
  • @assylias Can you explain what is actually happening? In the case of a `null` input, what is the boxed type of `n` that is throwing an exception with the case `(Integer)n`? This is not clear to me. Please post an answer. – Tim Biegeleisen Dec 03 '15 at 07:32
  • 3
    @Tim, since the second part of the expression is `n.intValue()` which gives an **primitive int**, the compiler uses unboxing on the first part as well... So `(Integer) n` becomes `((Integer) n).intValue()` in compiled code. So this throws a NPE on null input. Hope it clears. – Codebender Dec 03 '15 at 07:34

2 Answers2

4

Credit is completely due to @assylias who discovered the answer. Use this code instead:

public static Integer getInteger(Number n) {
    return (n == null || n instanceof Integer) ? (Integer)n : Integer.valueOf(n.intValue());
}

Because of weird boxing/unboxing rules, since n.intValue() returns a primitive int, the compiler was unboxing n in the expression (Integer)n to a primitive as well. And null cannot be assigned to a primitive (just try doing that in your IDE).

Edit:

The NPE is not really because null is being assigned to a primitive (the compiler would not do that), but it's because unboxing is done by calling Integer.intValue() method and the method is called on a null reference in this case.

Codebender
  • 14,221
  • 7
  • 48
  • 85
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
0

Because here:

return n == null || n instanceof Integer ? (Integer)n : n.intValue();
                                             here

You are trying to convert the n (which is null) to Integer.

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
KostasC
  • 1,076
  • 6
  • 20
  • 40