このJavaのコードは、文字列のインターン(interning)に関するものです。インターニングとは、文字列オブジェクトを再利用するために、文字列コンスタントプール内の同一の文字列への参照を使うプロセスです。intern()
メソッドは、このプール内にある文字列への参照を返します。もしプール内に同じ値の文字列が存在しない場合は、新たにプールに追加されます。
コードを見てみましょう:
public class Main {
public static void main(String[] args) {
String a = "abc";
String b = new String(a);
int count = 0;
if (a.intern() == "abc") { // 1
count++;
}
if (b.intern() == "abc") { // 2
count++;
}
if (a.intern() == b.intern()) { // 3
count++;
}
System.out.println(count);
}
}
a.intern() == "abc"
: ここでは、a
の値"abc"
は文字列リテラルなので、コンスタントプールにすでに存在します。a.intern()
はコンスタントプール内の"abc"
の参照を返します。そして、"abc"
も同じコンスタントプールの参照ですので、この比較はtrue
になります。カウンタcount
が1増えます。b.intern() == "abc"
:b
はnew
キーワードを使って明示的に新しいオブジェクトとして作られていますが、intern()
メソッドによってコンスタントプール内の"abc"
の参照を返します。このため、この比較もtrue
になり、カウンタcount
がさらに1増えます。a.intern() == b.intern()
:a.intern()
とb.intern()
は共にコンスタントプール内の"abc"
の同じ参照を返します。そのため、この比較もtrue
になり、カウンタcount
はもう1増えます。
最終的に count
の値は3になります。従って、コードの出力は 3
で、適切な選択肢は D. 3が表示される
です。
intern()
メソッド
intern()
メソッドは、ある String
オブジェクトが持つ文字列を、Javaのコンスタントプール内で検索します。もしコンスタントプール内に同じ文字列がすでに存在すれば、その文字列への参照を返します。存在しなければ、その文字列をプールに追加し、新しく追加された文字列への参照を返します。このプロセスにより、同じ文字列リテラルはメモリ上で一意の参照を共有することになるため、メモリ使用量を削減し、比較操作を効率化することができます。
補足
Javaのintern()
メソッドを使用した場合、その文字列がコンスタントプールに存在しない場合には、その文字列はコンスタントプールに追加されます。ここでの「存在しない」とは、文字列がまだコンスタントプールに登録されていない状態を指します。このプロセスは自動的に行われるので、開発者が手動でコンスタントプールに文字列を追加する必要はありません。
以下のコード例では、intern()
メソッドがコンスタントプールに新しい文字列を追加するプロセスを表しています。
String s1 = new String("example"); // ヒープ上に新しいStringオブジェクトを作成
String s2 = s1.intern(); // s1の文字列内容をコンスタントプールに追加し、その参照をs2に代入
String s3 = "example"; // この文字列リテラルは自動的にコンスタントプールに追加される
// s2とs3は、コンスタントプール内の同じ文字列"example"を指している。
System.out.println(s2 == s3); // trueが出力される。
この例では、s1
はnew
キーワードを使用して作成されているので、ヒープに格納された新しいString
オブジェクトです。s1.intern()
が呼び出されると、s1
が持つ文字列"example"
がコンスタントプールに追加され(もしまだ存在しない場合)、その参照がs2
に代入されます。その後、s3
に文字列リテラル"example"
が割り当てられますが、このリテラルは既にs1.intern()
によってコンスタントプールに追加されているので、s3
はコンスタントプール内の既存の"example"
への参照になります。したがって、s2
とs3
は同じ文字列の参照を指し、s2 == s3
はtrue
を返します。
Top comments (0)