When is it legal to compare objects and primitives with the operator '=='?

Is the law below (Java) legal?

class Test { Object foo() {return "";} boolean bar() {return foo() == true;} } 

It will not compile against JDK 6, but it looks great at 7+. Is the specification changed? Is the bug fixed? I discussed at http://bugs.eclipse.org/bugs/show_bug.cgi?id=416950 and could go for it anyway.

+6
source share
3 answers

As it turned out, it is impractical to compare the primitive with an expression such as the compilation time "Object". JLS 15.21 expressly forbids:

Equality operators can be used to compare two operands that are convertible ( ยง5.1.8 ) to a numeric type or two operands of type boolean or Boolean, or two operands, each of which has either a reference type or a null type. All other cases lead to a compile-time error.

The Eclipse compiler places an error regardless of the version of Java. For Java 7, both Oracle JDK and OpenJDK mistakenly allow you to compile code. This bug in Oracle and Open JDK is fixed in version 8.

Thus, this elusive comparison is illegal according to the specification and will compile only some subsets of compilers for a specific subset of the purposes of the language version. Will never work on Java 4- or 8+. The casting conversions mentioned in the other answers only apply to the '=' operator, not to '=='. 15.21.3 applies only to two reference operands.

+1
source

JLS regarding referential equality does not change between java 6 and 7:

Chapter 15.21.3: Link equality operators == and! = :

If the operands of the equality operator are both references, and the type or null type, then the operation is the equality of the object.

This is a compile-time error if it is not possible to convert a type or operand to the type of another by converting customization (ยง5.5). The run-time values โ€‹โ€‹of the two operands would necessarily be unequal.

However, I noticed some changes in Chapter 5.5: Casting Conversion . Casting boolean to Object seems to be classified as a Java 7 boxing convention:

A primitive type expression can undergo casting conversion to a reference type without errors, by converting the box.

enter image description here

โŠก means boxing conversion

Therefore, since primitive true can be added to Object , your equality expression can be classified as reference equality in Java 7 and does not give a compiler error

+3
source

Here is the byte code for the link

 class Test { Test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>": 4: return java.lang.Object foo(); Code: 0: ldc #2 // String 2: areturn boolean bar(); Code: 0: aload_0 1: invokevirtual #3 // Method foo:()Ljava/lang/Object; 4: iconst_1 5: invokestatic #4 // Method java/lang/Boolean.valueOf: 8: if_acmpne 15 11: iconst_1 12: goto 16 15: iconst_0 16: ireturn } 

Compiled with

 java version "1.7.0_25" Java(TM) SE Runtime Environment (build 1.7.0_25-b17) Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode) 

It seems to convert the returned String to a Boolean , which is unpacked.

0
source

Source: https://habr.com/ru/post/953599/


All Articles