2013-05-27 24 views
10

javac V1.7.0_15と`boolean`と` Object`の等価比較ができますか?とき、実行

public class TestComparison { 
    public static void main(String[] args) throws Exception { 
     boolean b = true; 
     Object o = new Boolean(true); 
     System.out.println("comparison result: "+ 
      (o == b)); // Eclipse complains about this expression 
    } 
} 

がエラーなしでコンパイル次のコード、および版画 "偽"。しかし、Eclipse Junoは、 "互換性のないオペランドタイプのObjectとboolean"について不平を言っています。

どうやらjavacは、プリミティブブールbをautoboxes、その後oを比較し、Eclipseがオートボクシングを行うことを拒否しながら、falseを得、オブジェクトの平等でbをautoboxed。

Java言語仕様に基づいた正しい動作はどれですか?どこにバグを記録すべきですか?

注:私はoBooleanの種類を変更する場合は、物事が期待どおりに動作:Eclipseはコードを受け入れ、コードのプリント「真」。

Runnable version on ideone.com

+1

あなたのEclipseの設定を確認し、ファンキーなものがあるかどう参照してください。 プロジェクトのプロパティ - > Javaコンパイラは - >エラー/警告 - >潜在的なプログラミングの問題 – blondeamon

+1

は何を「期待される」による - それは 'B'をボックスと参照の等価を使用する必要があります(falseを出力する)またはunboxを 'o'し、プリミティブブール値を使用する(trueを出力する)か? –

+0

[java AutoBoxing規則](http://jcp.org/aboutJava/communityprocess/jsr/tiger/autoboxing.html) –

答えて

7

それは、プロジェクトの言語レベル設定です。 Java 6のセマンティクスを持つJava 7コンパイラを使用している可能性があります。私はここにEclipseを持っていませんが、IntelliJで再現しました.IntelliJは、私が使用したコンパイラが7であっても、言語レベルがJava 6のときにエラーを出しました。 This linkで説明しています。

このコード:oBooleanに変更されたときにコードがコンパイルされ、動作することをあなたの '注意' をに関して

+1

これは問題のようです。私は 'javac -source 1.6'で問題を再現できるので、問題は1.6から1.7への変更によって引き起こされたようです。しかし、Eclipseでは、「Compiler compliance level = 1.7」のエラーが表示されます。これはEclipseコンパイラのバグかもしれません。 – sleske

+0

@sleske私はすべてを確認します:/ – A4L

3

public class Tester{ 
    public static void main(String args[]){ 
    Boolean one = new Boolean(true); 
    Object two = new Boolean(true); 
    boolean three = true; 
    System.out.println("SAME 1:2 " + (one == two) + " 1:3 " + (one == three) + " 2:3 " + (two == three)); 
    System.out.println("EQUAL 1:2 " + (one.equals(two)) + " 1:3 " + (one.equals(three)) + " 2:3 " + (two.equals(three))); 
    } 
} 

は、この結果を生成します。

SAME 1:2 false 1:3 true 2:3 false 
EQUAL 1:2 true 1:3 true 2:3 true 

理由を確認するにはこれは、のコンパイル時に、さまざまな式のタイプを考慮する必要があります。

  • one == twoObjectBooleanを比較する - これらは両方とも参照型であるので、試験が基準等価である(Java Language Specification, Java SE 7 edition, §15.21.3
  • one == threebooleanBooleanを比較する - これはプリミティブboolean値の比較として扱われます(§15.21.2); oneはアンボックスされ、threeと比較されます。
  • two == threebooleanObjectとを比較する - この場合booleanは(ObjectからBooleanを広げるこの場合ボクシング次いでBooleanbooleanとで、§5.5)キャスト変換によりObjectに変換され、両者が、基準等しいかどうかを比較しています。

EQUALラインがはるかに簡単です - すべての3例は、引数がthreeときにボクシングを使用して、Boolean.equals(Object other)への呼び出しです。

+0

説明をありがとう。したがって、 'two == three'の場合、キャストとボクシング/アンボクシングの両方が必要であり、Javaは最初に自動ボックスを行い、次にキャストします。 – sleske

関連する問題