4

昨日(2012年4月5日)私は環境にある文字列を比較しようとしています:

コンピューター1

  1. Java(TM)SEランタイム環境(ビルド1.6.0_29-b11-402-11D50b)
  2. OS X 10.7.3

コンピューター2

  1. Java(TM)SEランタイム環境(ビルド1.6.0_29-b11-402-11D50b)
  2. ウィンドウ7

コンピューター3

  1. Java(TM)SEランタイム環境(ビルド1.6.0_29-b11-402-11D50b)
  2. Linux Ubuntu 11.10

これは私が試しているコードです

public class TComp{
    public static void main(String[] args){
        String a = "arif";
        String b = "arif";
        if(a==b){
            System.out.println("match!");
        }
    }
}

私の知る限り、Javaで文字列を比較するには、.equal()関数を使用する必要があり、この場合は'=='がインターンを行います。しかし、OSが異なるすべてのコンピューターで、コンピューター2とコンピューター3でエラーが発生したのに、なぜインターンはコンピューター1で正常に機能するのでしょうか。

私が間違っている単語があれば訂正してください。ありがとうございました。

4

7 に答える 7

5

同じクラスで、すべての文字列定数は.class、コンパイラーによって(コンパイル時に)ファイル定数プールに折りたたまれます。これは、コンパイラが文字列のコピーを1つだけ格納することを意味します(プールに2つの同一の定数が必要なのは誰ですか?)。

これは、クラス内==で文字列の比較が機能することが多いことを意味します。ただし、興奮しすぎる前に==、文字列の比較を絶対に使用しないでください。 比較する2つの文字列が、クラス内の定数プールからのものであるという保証はありません。

それで、

"foo" == new String("foo")

完全に失敗する可能性がありますが

"foo" == "foo"

うまくいくかもしれません。これは実装に大きく依存する可能性があり、仕様ではなく実装にコーディングすると、仕様が実際にはその実装を必要としないため、実装が変更された場合に非常に厄介な驚きを感じる可能性があります。

つまり、毎回比較に使用.equals(...)します。プリミティブ比較と「これは同じオブジェクトインスタンスです」比較のみのためにObject予約してください。==2つがインターンされている(または同じオブジェクト)可能性があると思っていてもStrings、別のクラスローダー、別のJVM実装、または単にすべてをインターンしないことを決定したマシンでいつ実行されるかはわかりません。

于 2012-04-05T00:21:10.357 に答える
1

これは、コンパイル時定数文字列を作成するたびにJavaが文字列インターンを実行するためです。

JLS15.28。定数式

String型のコンパイル時定数式は、String.internメソッドを使用して、一意のインスタンスを共有するために常に「インターン」されます。

そのため、「==」を使用して比較するとtrueが得られます。これは、実際には同じオブジェクトであるためです。String.valueOf()は、文字列定数と同じように機能します。

String x = "a";
String y = "a";
System.out.println(x == y); // true


String w = new String("b");
String z = "b";
System.out.println(w == z); // false
于 2012-04-05T00:51:50.987 に答える
1

一方のコンピューターでは、それらは同じオブジェクトであり、もう一方のコンピューターではそうではありませんでした。言語のルールでは、それらが同じオブジェクトであるかどうかは指定されていないため、どちらの方法でも発生する可能性があります。

于 2012-04-05T00:04:05.640 に答える
1

文字列のインターンは完全にコンパイラに任されています。==何も「インターン」しません。オブジェクトのアイデンティティを比較するだけです。場合によっては、aとbが同じオブジェクトを指すことがあります。他の場合には、そうではありません。どちらも合法であるため、実際には.equals()を使用する必要があります。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5も参照してください。

于 2012-04-05T00:04:48.743 に答える
0

オブジェクトを比較するために==を使用することは、単純に信頼できません。まったく同じインスタンスを本当に探しているのでない限り、オブジェクトが等しいかどうかを比較するために==を使用しないでください。

于 2012-04-05T00:05:10.917 に答える
0

==演算子は、2つのオブジェクト参照が同じインスタンスを参照しているかどうかを判別します。

一方、.equals()メソッドは、オブジェクト内の実際の文字を比較します。

これらは、使用しているコンピューターとは無関係である必要があります。

于 2012-04-05T00:06:15.360 に答える
0

最良の方法は、常に.equalsを使用してオブジェクトを比較することです。ただし、Stringを使用する場合、==演算子を使用して何らかの奇妙な理由が必要な場合は、.internメソッドの結果を必ず比較する必要があります。それは常にインターンされた値を返し、ドキュメントはそれが一意であることを示します。ドキュメントによると、すべての定数はインターンされており、一意でもあります。

于 2012-04-05T00:42:47.420 に答える