どうしてこれなの?
String str1 = "one";
String str2 = "two";
System.out.println(str1.equals(str1 = str2)); // false, doesn't assignment of ref. to string object memory location happens after???
System.out.println(str1.equals(str1 = str2)); // true, same statement
模擬面接でこの質問をされたのですが、まだわかりません。
ベストアンサー1
答えはJava言語仕様15.7項の評価順序について説明しています。一般的には左から右に行われます。あなたの場合、評価は
- str1 を読み込む (から
str1.equals
) ->"one"
- str2 を読み込む ( から
str1 = str2
) ->"two"
- 値をstr1に格納する(から
str1 = str2
) -> str1は現在"two"
- 完全な式の値
str1 = str2
は です"two"
が、この文では str1 が最初のステップですでにロードされていることに注意してください。再度ロードされることはありません。 "one"
パラメータ"two"
-> falseを指定して、 equals on (すでにロード済み、上記参照) を呼び出します。
また、逆コンパイルされた Java コード (クラスパスで実行) を確認するとjavap -c ClassName
、この順序も表示されます。
0: ldc #7 // String one
2: astore_1
3: ldc #9 // String two
5: astore_2
[...]
9: aload_1 // <-- loads the value of str1
10: aload_2 // <-- loads the value of str2
11: dup
12: astore_1 // <-- stores to str1
13: invokevirtual #17 // <-- invokes equals
これは、str1 に格納した後にその値を再度読み込むことはありません。
言語仕様には、エッジケースとその処理方法の例がさらにいくつかあります (「関数の引数の 1 つが例外をスローする関数である場合に何が起こるか」など)。