Question

In Java, I can do the following to succinctly guard against a NullPointerException:

if ("myString".equals(someOtherString))

But I cannot do the same with Integers, e.g.

if (5.equals(someOtherInteger))

I get a compile-time error. Any ideas on why this design decision was made? Or any resources that might explain it? Thanks in advance.

EDIT: someOtherInteger is an Integer, not an int.

Was it helpful?

Solution

The JLS specifies that boxing conversions can only occur during assignment conversions, method invocation conversions, or casting conversions. Since you are neither assigning 5 to a variable, passing it as an argument to a method, nor explicitly casting it to Integer, it will not be autoboxed for you.

Assignment conversion (§5.2, §15.26) converts the type of an expression to the type of a specified variable.

Assignment conversion may cause an OutOfMemoryError (as a result of boxing conversion (§5.1.7)), a NullPointerException (as a result of unboxing conversion (§5.1.8)), or a ClassCastException (as a result of an unchecked conversion (§5.1.9)) to be thrown at run-time.

Method invocation conversion (§5.3, §15.9, §15.12) is applied to each argument in a method or constructor invocation and, except in one case, performs the same conversions that assignment conversion does.

Method invocation conversion may cause an OutOfMemoryError (as a result of boxing conversion (§5.1.7)), a NullPointerException (as a result of unboxing conversion (§5.1.8)), or a ClassCastException (as a result of an unchecked conversion (§5.1.9)) to be thrown at run-time.


Casting contexts allow the use of one of:

...

a boxing conversion (§5.1.7) optionally followed by a widening reference conversion (§5.1.5)

OTHER TIPS

String has always been an object in Java. There is no autoboxing for strings, and there can't be in principle. Autoboxing from the primitive int to the Integer object has been introduced fairly recently.

It is valid to ask why trying to access member variables of primitives doesn't invoke autoboxing (95.toString(radix) would actually be pretty convenient), but I imagine that the reason is that it wasn't considered a likely use-case, since since almost every wrappedPrimitive.method() has an equivalent WrapperClass.method( primitive ) version.

equals() is usually unnecessary for primitive types since == is already there. However, you do make a good case for it as a null-guard... 5 == integerInstance will try to unbox the instance, and throw a NullPointerException if the instance is null, unfortunately. (I didn't fully appreciate your point at first.)

That said, it would be really cool if we could hear from someone working on Java either currently or at the introduction of autoboxing about whether they considered this sort of functionality.

you can use

if (someOtherInteger!=null && someOtherInteger == 5)

I suspect that autoboxing is not implemented for the literal 5, whereas it is for a string myString, as a safety measure. It's safe to autobox a syntactic structure that is prepended and appended with double quotation marks "", because it's unlikely that the quotation marks are unintended, so the user's intention is clear and type-safety is not compromised.

However, the literal 5 could be a typo on the user's part - or it could be intended to be a string, rather than an integer. Therefore, to maintain the benefit that variables must be declared before use in object-oriented programming in order to prevent typos (among many other advantages) (even if it's implicit, as in the case of autoboxing), 5 is not autoboxed.

Here is a bit of reading on the different comparisons: http://www.leepoint.net/notes-java/data/expressions/22compareobjects.html

Not sure if it was a built in design to reject int

If you do

Integer s=5;
Integer d=5;
if(d.equals(s)){
    System.out.println("Fun");
}

It works just fine.

int is a primitive type it doesn't support any methods itself. To compare 2 ints you simply use the == convention as in:

if(a == b) 

There is an Integer class that is a wrapper for an int that supports some other method calls

Edit:

Based on your edit you want to compare to Integer but the problem is the literal 5 isn't an Integer you have to create a new integer for it.

Integer myInt = 5;
if(myInt.equals(someOtherInteger)) ...

This design is inherent in the fact that primitives don't have any methods. As to whether primitives should support methods (or simply not exist) is integral to the debate as to whether Java is a Pure Object Oriented Language or not (many say no due to the fact that primitives exist).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top