There has been a lot of discussion among my colleagues about the evilness of auto unboxing in Java. The evilness can be easily demonstrated:
int x = null;
if (x == 0) {}; // this throws a NullPointerException
The argument on why this is evil is that in pre-Java 1.5 days, developers would have written the following equivalent instead:
if (x.intValue() == 0) {}; // still throws a NullPointerException
When they typed the ".intValue()" they would realize that they needed to add a null check:
if (x!=null && x.intValue() == 0) {}; // No NPE here
The other case for evilness is imagine somebody created the following API:
public void foo(Integer i);
And then changed the signature to:
public void foo(int i);
In pre-Java 1.5 days, any clients of foo() would have compilation errors, thus alerting "people" that they needed to add null-checking code. With Java 1.5+, there would be no compilation errors, so there is obviously a chance for Something Bad To Happen.
You might have noticed that I've been distancing myself from these arguments. I don't really buy them and tend to argue the other side. Auto unboxing is just a new language feature that you had better understand before you use it. If you understand it, then of course you will write
if (x!=null && x == 0) {}; // no NPE here either
And you will change your API as:
@Deprecated public void foo(Integer i);
public void foo(int i);
The real antidote is developer knowledge and good testing to catch the corner cases.
A lot of my colleagues would like an option in Eclipse to cause a compiler error whenever auto unboxing could cause problems. IntelliJ IDEA gives a warning. Maybe there's an option for it to give an error instead of a warning.
I remember when unboxing was a JSR. It was definitely the most controversial part of JSR 201. Many people argued for default values to avoid the NPE problem. That would have been horrible, IMO. Of course C# has the advantage here. That's because they had boxing/unboxing from day one. You can't write Double x = null; --- it won't compile. You can do something like Object x = null; Double d = (Double) x; ... but you're really trying to throw an exception at that point.
This is one of the Important and knowledgeable post.I like your blog Instruction.supper.
ReplyDelete