aspose file tools*
The moose likes Java in General and the fly likes Can the (non-)equality operator cause auto-boxing? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Can the (non-)equality operator cause auto-boxing?" Watch "Can the (non-)equality operator cause auto-boxing?" New topic
Author

Can the (non-)equality operator cause auto-boxing?

Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
Hi,

I was wondering whether anyone knows the answer to the question in this post's subject? I started thinking about it when going through the Sierra/Bates SCJP6 book and posted it in the certification section of this forum earlier (cfr. http://www.coderanch.com/t/600951/java-programmer-SCJP/certification/sierra-bates-ch-test-Combination) , but didn't receive any useful response over there.

Thanks in advance!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39415
    
  28
What does it say in the Java Language Specification?
Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
Thanks for that link!

The cases covered are:

- {numeric, numeric}, {numeric, convertibleToNumeric}
- {boolean, boolean}, {boolean, convertibleToBoolean}
- {ref, ref}

Assuming the language specification is exhaustive and given that {numeric, ref} is missing. That indeed answers my question with 'no'.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19720
    
  20

You missed one small little line in section 15.21.1:
Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Rob Spoor wrote:You missed one small little line in section 15.21.1:
Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).

But an unboxing conversion is quite different than a boxing conversion, especially in the case of equality. For example:

If the value in the referenceInt is unboxed, you would expect the the comparison to be true, because you would be doing numeric comparisons, while if the primitiveInt was boxed you could expect the result to be false, because 6000 is probably not a cached Integer value.


Steve
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39415
    
  28
Shame you missed the line about unboxing. That covers the case where one value is numeric and the other value is convertible to a numeric type, so all possibilities are covered in that JLS link. I think everybody else has covered the whole answer.
Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
Campbell Ritchie wrote:Shame you missed the line about unboxing.


Is this addressed to me? If so, as Steve mentioned, I don't consider unboxing as auto-boxing. If I understand correctly, boxing is a primitive to object conversion, not the other way around (which is "unboxing").

When I talked about the {numeric, ref} case, the 'ref' in there is not convertible to a numeric primitive (i.e., cannot be unboxed). I don't see that case covered in the JLS.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39415
    
  28
That case is indeed covered by the JLS link I quoted. It says if one is numeric and the other convertible to numeric…, with a link to §5.18 which says that an Integer is convertible to an int by unboxing, so that covers <int, Integer> and <Integer, int>.
You are quite right that boxing and unboxing are different things, and Steve has shown how the two would produce different results.
Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
Campbell Ritchie wrote:That case is indeed covered by the JLS link I quoted. It says if one is numeric and the other convertible to numeric…, with a link to §5.18 which says that an Integer is convertible to an int by unboxing, so that covers <int, Integer> and <Integer, int>.

You are talking about the {numeric, convertibleToNumeric} case, which I listed in the covered cases list.

I really think you are not reading the 'not' in my sentence stated earlier:
When I talked about the {numeric, ref} case, the 'ref' in there is not convertible to a numeric primitive (i.e., cannot be unboxed).

I do not see this {numeric, refNotConvertibleToNumeric} case in the JLS.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8008
    
  22

Wout Er wrote:If so, as Steve mentioned, I don't consider unboxing as auto-boxing.

Strictly speaking, you're probably right; however, the term auto-boxing refers to actions taken automatically to convert between values and wrappers, and I've often heard it used in either direction. 'Auto-unboxing' is also a bit of a mouthful.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39415
    
  28
I don’t mean to appear rude, or anything like that, but I think that case is covered.

One is numeric and the other convertible to numeric. That does not mean {numeric, convertible} alone; it includes {convertible, numeric}.
A {numeric, NOTconvertible} pair would of course result in a compiler error.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39415
    
  28
I would appear to be mistaken. sorry
so, although it says nothing about boxing in the JLS, the i must be boxed to an Integer. Otherwise you would get true. I have 2GB memory on this computer, so the int type can cover all memory locations available.
Sorry for my mistake.
Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
I'm not sure what compiler you're using but I'm using 1.6.0_37 on a mac and the following does not compile at all:


Message:


In addition, the only (strange!) reason that your second piece of code seems to be compiling is a weird implementation of the equals operator.
Try changing line 6 to:

and it no longer compiles:
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Interesting:

vs.


In Java 1.6.0.3 (Windows) the first fails, the second works. On Java 7.0.3 they both work for me. The same pattern happens on Ideone (http://ideone.com/S374Kl) but I don't know what OS it uses.
Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
Indeed interesting. Yet, since it's not specified in the JLS, this seems to be platform-specific and therefore I only trust the 'No' answer to the question posed in the subject.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2316
    
  49
Wout Er wrote:Indeed interesting. Yet, since it's not specified in the JLS, this seems to be platform-specific and therefore I only trust the 'No' answer to the question posed in the subject.

Actually it is specified in the JLS.

Comparing an int to an Object means it no longer comes under the section "15.21.1. Numerical Equality Operators == and !=" but rather it comes under the section "15.21.3. Reference Equality Operators == and !=" where it says

It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.

The casting conversion specified in 5.5 allows for an auto-boxing conversion and so the int is converted to an Integer and the two object's are compared to see if they are the same object.
Wout Er
Greenhorn

Joined: Nov 26, 2012
Posts: 15
Tony Docherty wrote:
Comparing an int to an Object means it no longer comes under the section "15.21.1. Numerical Equality Operators == and !=" but rather it comes under the section "15.21.3. Reference Equality Operators == and !=" where it says

It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.

The casting conversion specified in 5.5 allows for an auto-boxing conversion and so the int is converted to an Integer and the two object's are compared to see if they are the same object.


The first line of 15.21.3 says:

If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality.

which, at least to me, seems to indicate that what's underneath is only applicable if that condition is met and therefore not when one of both operands is a primitive.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39415
    
  28
I think I agree with you that the paragraphs are confusing. There appears to be a difference between Java6 and Java7 in its behaviour towards ob == 123 and boxing. This is what the Java5 (3rd edition) Language Specification says:-
15.21.3 Reference Equality Operators == and !=

If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality.
A compile-time error occurs if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.
At run time, the result of == is true if the operand values are both null or both refer to the same object or array; otherwise, the result is false.
The result of != is false if the operand values are both null or both refer to the same object or array; otherwise, the result is true.
While == may be used to compare references of type String, such an equality test determines whether or not the two operands refer to the same String object. The result is false if the operands are distinct String objects, even if they contain the same sequence of characters. The contents of two strings s and t can be tested for equality by the method invocation s.equals(t). See also §3.10.5.
And, would you believe, the Java7 edition says:-
15.21.3. Reference Equality Operators == and !=

If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality.

It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.

At run-time, the result of == is true if the operand values are both null or both refer to the same object or array; otherwise, the result is false.

The result of != is false if the operand values are both null or both refer to the same object or array; otherwise, the result is true.

While == may be used to compare references of type String, such an equality test determines whether or not the two operands refer to the same String object. The result is false if the operands are distinct String objects, even if they contain the same sequence of characters (§3.10.5). The contents of two strings s and t can be tested for equality by the method invocation s.equals(t).
Apart from the fact that the newer edition has pretty red headings, can anybody discern a difference there? If you go to §5.5 both versions permit boxing and unboxing, in Java7 possibly with an associated widening conversion. I can still see no explanation for the different behaviour.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2316
    
  49
Wout Er wrote:which, at least to me, seems to indicate that what's underneath is only applicable if that condition is met and therefore not when one of both operands is a primitive.

Note: this would never apply if both operands were primitives. Nor would it apply if one operand was a primitive and the other could be converted to a primitive via unboxing.

The line you have quoted does apply if the primitive is converted via auto-boxing to an Object type, but I agree that it isn't at all clear what the behaviour should be.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can the (non-)equality operator cause auto-boxing?