質問するログイン新規登録

回答編集履歴

2

誤記

2018/05/06 15:56

投稿

KSwordOfHaste
KSwordOfHaste

スコア18406

answer CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  String#internはそれなりに高速ではありますが、無視してよいほど高速なわけではありません。
22
22
 
23
- (C)のような演算結果"abc"という文字列をString#internにより定数プールへ登録するような真似をするとJavaプログラム全体が致命的な速度低下を招くだろうと思います。それゆえ演算結果はinternされず結果としてコンスタントプールに存在する文字列リテラルと例えたまたま内が一致していたとしても「異なるインスタンス」となると思ってください。
23
+ (C)のような演算結果"abc"という文字列をString#internにより定数プールへ登録するような真似をするとJavaプログラム全体が致命的な速度低下を招くだろうと思います。それゆえ演算結果はinternされず結果としてコンスタントプールに存在する文字列リテラルと(例えたまたま内が一致していたとしても)「異なるインスタンス」となると思ってください。
24
24
 
25
25
  ---
26
26
  追記:コンパイル時に連結されるケースに配慮して説明を変更しました。

1

間違いを訂正

2018/05/06 15:56

投稿

KSwordOfHaste
KSwordOfHaste

スコア18406

answer CHANGED
@@ -1,15 +1,26 @@
1
1
  ソース上にある"abc"のような文字列リテラル(文字列定数と思ってもいいですが)は同じ内容なら同じインスタンスを指すのですが、演算して新たなインスタンスが生成されるともはやそれはリテラルではなくなります。
2
2
 
3
- `String a = "abc";`
3
+ (A) `String a = "abc";`
4
4
 
5
5
  aにはリテラルの参照が入っています。
6
6
 
7
- `String a = "ab" + "c";`
7
+ (B) `String a = "ab" + "c";`
8
8
 
9
- aに入っているは"abc"とい文字列ですそれは文字列を連結した演算結果であってリテラルの参照ではありません
9
+ な単純ケースもコンパイラーコンパイル時に連結演算をやってくれるためリテラルの参照がaに入りましかし
10
10
 
11
+ (C)
12
+ ```Java
13
+ String a1 = "ab";
14
+ Stirng a2 = "c";
15
+ String a = a1 + a2;
16
+ ```
17
+ このくらいになるともはやコンパイラーは「aの中身が"abc"になるはず」という推論をあきらめちゃいます。そのため実行時に演算することになりますが、文字列を連結した演算結果であってリテラルの参照にはなりません。
18
+
11
19
  文字列リテラルが同一のインスタンスになる仕組みはコンパイラーがクラスをロードしたとき、クラスファイルの中に含まれる「ソース上に記述した文字列リテラル」を全てString#internで同一のStringインスタンスに集約する手間をかけているからです。
12
20
 
13
21
  String#internはそれなりに高速ではありますが、無視してよいほど高速なわけではありません。
14
22
 
15
- `String a = "ab" + "c";`のような演算結果"abc"という文字列をString#internにより定数プールへ登録するような真似をするとJavaプログラム全体が致命的な速度低下を招くだろうと思います。それゆえ演算結果はinternされず結果としてコンスタントプールに存在する文字列リテラルと例えたまたま内奥が一致していたとしても「異なるインスタンス」となると思ってください。
23
+ (C)のような演算結果"abc"という文字列をString#internにより定数プールへ登録するような真似をするとJavaプログラム全体が致命的な速度低下を招くだろうと思います。それゆえ演算結果はinternされず結果としてコンスタントプールに存在する文字列リテラルと例えたまたま内奥が一致していたとしても「異なるインスタンス」となると思ってください。
24
+
25
+ ---
26
+ 追記:コンパイル時に連結されるケースに配慮して説明を変更しました。