[解決済み】Javaでfinalと宣言されている==の文字列を比較する。
質問
Javaでの文字列について簡単な質問があります。次の簡単なコードは、2つの文字列を連結し、それらを
==
.
String str1="str";
String str2="ing";
String concat=str1+str2;
System.out.println(concat=="string");
比較式
concat=="string"
は以下を返します。
false
を自明のこととして(私は
equals()
と
==
).
この2つの文字列が宣言されたとき
final
というように
final String str1="str";
final String str2="ing";
String concat=str1+str2;
System.out.println(concat=="string");
比較式
concat=="string"
を返すが、この場合は
true
. なぜ
final
は違いがあるのでしょうか?インターンプールと何か関係があるのでしょうか、それとも私が誤解しているだけなのでしょうか?
解決方法は?
を宣言すると
String
(これは
不変
) 変数を
final
で初期化すると、これもコンパイル時定数式となり、その値が使用されるコンパイラでインライン化される。つまり、2番目のコード例では、値をインライン化した後、文字列の連結はコンパイラによって次のように変換されます。
String concat = "str" + "ing"; // which then becomes `String concat = "string";`
と比較すると
"string"
を使うと
true
というのは、文字列リテラルは
インターン
.
プリミティブ型または型の変数
String
ということです。final
と呼ばれ、コンパイル時の定数式(15.28節)で初期化されます。 定数変数 .
また、以下より JLS §15.28 - 定数式。
型のコンパイル時定数式
String
は常に "interned"。 というメソッドを使って、一意なインスタンスを共有するようにします。String#intern()
.
最初のコード例では、このようなことはありません。
String
変数が
final
. つまり、これらはコンパイル時の定数式ではありません。そこでの連結操作は、実行時まで遅延され、その結果、新しい
String
オブジェクトを作成します。このことは、両者のバイトコードを比較することで確認できます。
最初のコード例
(非
final
バージョン)
は、以下のバイトコードにコンパイルされます。
Code:
0: ldc #2; //String str
2: astore_1
3: ldc #3; //String ing
5: astore_2
6: new #4; //class java/lang/StringBuilder
9: dup
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_3
29: ldc #9; //String string
31: if_acmpne 38
34: iconst_1
35: goto 39
38: iconst_0
39: invokevirtual #10; //Method java/io/PrintStream.println:(Z)V
42: return
明らかに保存している
str
と
ing
を2つの別々の変数で使用し
StringBuilder
で連結操作を行う。
一方、2つ目のコード例では
(
final
バージョン)
はこのように見えます。
Code:
0: ldc #2; //String string
2: astore_3
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_3
7: ldc #2; //String string
9: if_acmpne 16
12: iconst_1
13: goto 17
16: iconst_0
17: invokevirtual #4; //Method java/io/PrintStream.println:(Z)V
20: return
そこで、最後の変数を直接インライン化し、Stringを作成します。
string
によって読み込まれます。
ldc
の操作で、ステップ
0
. 次に、2番目の文字列リテラルが
ldc
の操作で、ステップ
7
. これは、新しい
String
オブジェクトを実行時に作成します。Stringはコンパイル時に既に知られており、それらはインターンされる。
関連
-
[解決済み] Java enumのメンバーを比較する:==またはequals()?
-
[解決済み] トークンのシンタックスエラー、これらのトークンを削除してください [closed].
-
[解決済み] ボタンでTextFieldをクリアする(Java)
-
[解決済み] 一部の入力ファイルが非推奨のAPIを使用またはオーバーライドしている
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] と'is'のどちらかを使って文字列を比較すると、異なる結果になることがあるのはなぜですか?
-
[解決済み] Javaで文字列を比較するには?
-
[解決済み] Javaにおける "final class "の意味とは?
-
[解決済み] Javaの "final "キーワードはどのように機能するのでしょうか?(オブジェクトを修正することは可能です。)
-
[解決済み] Javaリフレクションを用いた静的なプライベートfinalフィールドの変更
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] java.sql.SQLException: ORA-00933: SQL コマンドが正しく終了していません。
-
[解決済み] maven. -source 1.5ではラムダ式がサポートされていません。
-
[解決済み] HashMapのtoString関数はなぜ異なる順序で自分自身を印刷するのですか?
-
[解決済み] ストリングビルダー.イコール Java
-
[解決済み] XX:MaxDirectMemorySizeの既定値
-
[解決済み] javacが「using unchecked or unsafe operations」という警告を出す原因は何ですか?
-
[解決済み] 最も近い整数への切り捨て - 私は不正をしているのでしょうか、それともこれは十分すぎるほど適切なのでしょうか?
-
[解決済み] eclipseからTomcatに物理的に発行されるmyjspはどこにあるのでしょうか?
-
[解決済み] java.lang.ClassCastException: java.lang.Long を java.lang.Integer にキャストできない(java 1.6
-
[解決済み] x--やx++はここで何をするのですか?