2013-09-11 13 views
6

下記(Java)コードは合法ですか?オブジェクトとプリミティブを '=='演算子で比較するのはいつ適切ですか?

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

これはJDK 6に対してコンパイルされませんが、7+では問題ありません。仕様が変更されましたか?バグは修正されましたか?私はhttp://bugs.eclipse.org/bugs/show_bug.cgi?id=416950で議論していましたが、いずれにしてもこれに行くことができます。

+2

[autoboxing java6とjava7の違い](http://stackoverflow.com/questions/16119638/differences-in-auto-unboxing-between-java-6-vs-java-7)を参照してください。 – nachokk

答えて

1

このように、プリミティブとコンパイル時のタイプ 'Object'の式を比較すると、でなく、となります。 JLS 15.21は明示ことを禁止:

等価演算子は、数値型、またはboolean型 またはブールの二つのオペランド、またはいずれかの各二つのオペランドに変換 (§5.1.8)である2つのオペランドを比較するために使用することができますヌルタイプの です。それ以外の場合は、コンパイル時にエラーが発生します。

Javaコンパイラは、Javaのバージョンに関係なくエラーにフラグを付けます。Java 7では、Oracle JDKとOpenJDKの両方で、コードのコンパイルが誤って許可されます。

要するに、このうわーしい比較は仕様に違反しており、特定の言語バージョンのターゲットのコンパイラの一部のサブセットでのみコンパイルされます。 Java 4または8+で動作することはありません。他の回答で参照されているキャスト変換は '='演算子にのみ適用され、 '=='には適用されません。 15.21.3は、2つの参照オペランドにのみ適用されます。

0

は、ここでそれはアンボクシング取得Booleanに返さStringを変換しているようだ

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) 

でコンパイル参照

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 
} 

のためのバイトコードです。基準等価約

3

JLSは、Java 6 & 7との間で変化しない。

Chapter 15.21.3: Reference Equality Operators == and !=

等価演算子のオペランドが参照 型またはヌル型のいずれの両方が、その後、ある場合操作はオブジェクトの平等です。

キャスト変換 (§5.5)によっていずれかのオペランドと他の型の型を変換できない場合は、コンパイル時エラーです。 2つのオペランドの実行時の値は、必ずしも に等しくなりません。

しかし、私はChapter 5.5: Casting Conversionの変更を気付きました。オブジェクトにブールを鋳造は、Java 7にボクシングの規則として分類されると思わ:

プリミティブ型の発現は、ボクシング変換により、エラーなし 参照型にキャスト変換を受けることができます。

enter image description here

は⊡ボクシング変換を意味

プリミティブ trueObjectにキャストすることができますので、したがって、あなたの等価式は、Java 7上の基準平等に分類することができ、コンパイラエラーが得られない

関連する問題