Is the Java equality operator commutative?

Consider the following Java code:

Integer foo = bar(); if(foo == 5) ...; if(5 == foo) ...; 

Are these comparisons consistent, in particular, the ability of foo be null ? Do they expand to foo.getValue() == 5 and 5 == foo.getValue() , or to something closer to foo.equals(new Integer(5)) and new Integer(5).equals(foo) , or to something else? Can one or the other or both or no one throw an NPE?

+7
java syntactic-sugar autoboxing
source share
3 answers

From JLS :

15.21.1. Equals operators == and! =

If the operands of the equality operator are both numeric, and one is of the numeric type and the other is convertible (Section 5.1.8) to the numeric type, binary numeric promotion is performed along the operands (Β§5.6.2).

And the corresponding rule from 5.1.8:

If r is an Integer reference, then unboxing converts r to r.intValue ()

And 5.6.2 says:

5.6.2. Binary numeric promotion

When an operator applies binary numeric promotion to a pair of operands, each of which must indicate a value that can be converted to a numeric type, the following rules apply to:

If any operand has a reference type, it is unpacked (Β§5.1.8).

This means that if(foo == 5) ...; means the same as if(foo.intValue() == 5) ...; , and if(5 == foo) means if (5 == foo.intValue()) . If foo is null , then you will get NPE anyway.

+1
source share

== symmetrical ; those. for any values ​​of x and y , (x == y) == (y == x) . This is the guarantee provided to us by JLS Β§15.21.1 for numbers, and Β§15.21.3 for reference types (or anything that is not a primitive value).

It can also be considered as transitional , if there are three values x, y, z and x == y && y == z , then x == z . This is again provided by the same JLS specification - just repeated to reduce the problem with the common variable y .

A real problem arises regarding autoboxing; when you go to unbox null , then using JLS , you will get a NullPointerException - regardless of the comparison operation that you are "Next."

Effectively:

  • You have the primitive boxed type on the one side of the comparison, and the primitive on the other. The value has not yet been considered.

  • Given that the primitive value will force a numerical comparison because it is a boxed primitive, Java will then try to unpack the value in the box.

  • You cannot unpack null , hence NullPointerException .

This is (the view) where equals() takes effect - under his contract, two non-empty instances must be equivalent to each other if they are really the same. If either (but not both) of these values ​​is null , then they are not the same instance.

I say "kinda" because Object#equals really have nothing to enforce the intended contract; you could (with some effort) write the asymmetric equals() method, although you might wonder why you would like to.

+1
source share

1) There is no difference between 1 and 2

2) The compiler converts foo == 5 to foo.intValue() == 5 (outboxing)

3) If foo is null NPE throws at runtime

0
source share

All Articles