Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is an int-to-Object comparison valid in Java 7, but not in Java 8?

Tags:

java

The following code,

private boolean compare(Object a, int b) {     return a == b; } 

compiles in Java 7, but it results in the following error in Java 8:

incomparable types: int and Object

Looking at the following question:

Comparing Object and int in Java 7

It seems like Java 6 and Java 8 don't let you compare int and Object, while 7 does. Is there any documentation on this?

I'm interested in the background knowledge that informed these decisions. It seems like they were undecided or something.

I'm using IntelliJ IDEA 14.1.4 with JDK 1.7.0.51.

like image 521
Matt_Bro Avatar asked Sep 17 '15 14:09

Matt_Bro


People also ask

Can we compare two integers in Java?

Java Integer compare() methodpublic static int compare(int x, int y) Parameter : x : the first int to compare y : the second int to compare Return : This method returns the value zero if (x==y), if (x < y) then it returns a value less than zero and if (x > y) then it returns a value greater than zero.

Can we compare two objects in Java?

In Java, the == operator compares that two references are identical or not. Whereas the equals() method compares two objects. Objects are equal when they have the same state (usually comparing variables). Objects are identical when they share the class identity.

How do you compare two integers equal in Java?

To check two numbers for equality in Java, we can use the Equals() method as well as the == operator. Firstly, let us set Integers. Integer val1 = new Integer(5); Integer val2 = new Integer(5); Now, to check whether they are equal or not, let us use the == operator.


2 Answers

Java 7 applies autoboxing to the int.

 private boolean compare(java.lang.Object, int);    Code:       0: aload_1       1: iload_2       2: invokestatic  #2       // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;       5: if_acmpne     12       8: iconst_1       9: goto          13      12: iconst_0      13: ireturn 

I created this with build 1.7.0_71-b14

EDIT:

This behaviour was recognized and treated as bug by Oracle:
JDK-8013357: Javac accepts erroneous binary comparison operations

Relevant JLS section is 15.21. Javac seems to treat this as a reference comparison, but a reference comparison is only allowed when BOTH operands are reference types.
...
The type rules for binary comparisons in JLS Section 15.21 will now be correctly enforced by javac. Since JDK5, javac has accepted some programs with Object-primitive comparisons that are incorrectly typed according to JLS 15.21. These comparisons will now be correctly identified as type errors.

like image 69
wero Avatar answered Oct 11 '22 12:10

wero


The JLS - Chapter 15. Equality Operators mentions 3 different == operators: numerical, boolean and reference. None of the == operators can happen in your example, so we conclude that the statement is illegal.

Let's see why == cannot be applied in your example:

  • 15.21.2. Boolean Equality Operators == and !=

    No need to mention why it's not relevant..

  • 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.

  • 15.21.1. Numerical Equality Operators == and !=

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

Now let's assume it's legal and the compiler changed the line to:

if (a == new Integer(b)) 

What do you expect the result to be? The condition will never evaluate to true, so it makes sense that it's a bug that was fixed in Java 8.

like image 35
Maroun Avatar answered Oct 11 '22 12:10

Maroun