Solved

Null Pointer on conditional initialisation with a method call

Posted on 2009-03-31
8
193 Views
Last Modified: 2013-11-23
Hi,

Given the following code, why on the last initialisation of variable "f" do I get a NullPointerException? The examples before, "a-e" seem to indicate there shouldn't be a problem with it.

Integer a = true?1:2;
Integer b = false?1:2;
Integer c = getTest();
Integer d = true?1:getTest();
Integer e = false?1:null;
Integer f = false?1:getTest();

Where getTest is:

private Integer getTest() {
      return null;}
0
Comment
Question by:sl311
  • 4
  • 2
  • 2
8 Comments
 
LVL 13

Accepted Solution

by:
Bart Cremers earned 125 total points
ID: 24027836
Because the return value of your ternary operation is a primitive int, it will try to parse to an int before autoboxing this again to an Integer object. Parsing null will not work.

In a and b both values are primitive ints. C is no problem as there is no autoboxing involved. In d, the value is always primitive int 1, which will get autoboxed. In e the primitive will get autoboxed to an Integer object, so only f gives a problem.
0
 

Author Comment

by:sl311
ID: 24027971
Thanks,

So the "?" operator checks the return type of BOTH possible values, and if EITHER is an "int", it will pass any Integer to an int before autoboxing again to an Integer ? The following seems to confirm this (g works, h fails)

Integer g=false?new Integer(1):getTest();
Integer h=true?getTest():1;

That doesn't seem a very logical way to apply autoboxing to the "?" operator - wouldn't it be better to apply autoboxing to the return value only if it needs it ?

Unnecessarily doing an Integer -> int -> Integer conversion will take extra time, and causes the failure of what looks like a reasonable statement.
0
 
LVL 13

Expert Comment

by:Bart Cremers
ID: 24028047
h fails for the same reasons as f. g works because you explicitely tell it to use an Integer object.

I totally agree with you that it's not logical to unbox/box in sequence, but there probably is a technical reason for this in the compiler or VM.

You should read up on the conditional operator (15.25) and binary numeric promotion (5.6.2) in the language spec:

http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html
0
ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 
LVL 26

Expert Comment

by:ksivananth
ID: 24028082
actually this is not because of autoboxing but because of the optimization done by compiler!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24028099
the compiler understand the code/staement Integer f = false?1:getTest(); and thinks that it is inefficient! So it compiles that code into a optimized way as below,

Integer f = Integer.valueOf(getTest().intValue());

so that it can avoid the unnecessary checking at runtime!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24028126
in case of Integer d = true?1:getTest();
it will be compiled as Integer d = Integer.valueOf(1);
0
 

Author Comment

by:sl311
ID: 24028234
I think it might be compiled like that because I've used true or false in my examples - in reality these would be determined at run time, so the autoboxing and conditional operator mentioned in Bart CR's links are the reason for this behaviour.

Still seems wrong to me (what if I have subclassed Integer to MyInteger for example - by going through this MyInteger -> int -> MyInteger process it would lose any extra information that method had put onto MyInteger)

At least I know now - thankyou for your help. I've changed the original problematic line to:

Integer f = false?(Integer)1:getTest();

And it seems to work fine.
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24028265
>>what if I have subclassed Integer to MyInteger

you can't becuase the wrappers( Integer, Double... ) are final!
0

Featured Post

Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
groupNoAdj 7 95
xampp tool 12 49
type mismatch (Object[] to double[] 4 24
spring jars download 1 27
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question