是不是定义字符串如果不使用new来初始化的话相同的字符串会被定义成一个引用
闭关修行中......
JVM は、String 定数プール を持つという点で、String のストレージに関して少し特殊です。 この定数プールには、String オブジェクトへの参照が含まれています。 String的存储有一点特殊的地方在于有一块String常量池。这个常量池里面存着对String对象的引用。
String 定数プール
String
String常量池
比如,String s = "abc"会先去String常量池中查找有没有已经存在的引用,如果没有,声明的abc会直接生成一个String对象,并且会在String常量池中存入一个引用指向这个String对象。
String s = "abc"
之后直接声明的字符串同样也会遵循上面的步骤,所以第二次String s2 = "abc"从String常量池中找到了一个引用指向第一次声明的字符串对象。
String s2 = "abc"
而new String("abc")这样会直接在堆中创建新的对象,不会进入String常量池。要把这样的对象引用放入常量池中就涉及另一个String类的方法intern(),这个方法就是返回一个String对象的常量池引用。如果这个对象不在常量池中,就会把这个String对象放入常量池中并返回对应的对象引用。
new String("abc")
intern()
题主第一个截图的方法str2.intern() == str3.intern()这样使用也会返回true,调用intern()返回的String常量池
str2.intern() == str3.intern()
true
String constant pool
Java の非組み込みデータ型はすべて参照です。
String s = new String("xx"); このメソッドはメモリ空間を作成し、参照 s がそれを指すようにします。
String s = "xx"; このメソッドは、参照 s が共有スペースを指すようにします。
new を使用して作成された場合、str2 と str3 は異なるメモリ空間を指すため、str2 と str3 は等しくありません。
文字列割り当てが直接使用される場合、str2 と str3 は同じメモリ空間を指すため、str2 と str3 は等しくなります。
str2.equals(str3) を使用して文字列の内容を比較できます。
1 つは定数プールに保存する方法、もう 1 つはヒープに新しいオブジェクトを作成する方法です
プロセスを理解するのに役立ちます。 Java には、覚えておくべきポイントがいくつかあります 1. すべての文字列は、不変の CONSTANT_String_info に対応する定数プールに生成されます。 2. 通常のオブジェクトはほとんどの場合ヒープ内に生成されます (もちろん、メソッド領域に生成されるクラス オブジェクトなどの特殊なオブジェクトもあります。これはさまざまな仮想マシンの実装に依存し、仮想マシンの仕様は異なります)必須)3.= =この決定を行うとき、参照型の場合、最終分析はメモリ アドレスを比較することです。
さて、以上の概念ができました。最初の質問では、 String s1 = new String("aaa"); 新しいオブジェクトを作成するとき、jvm はヒープ上にオブジェクト空間を開くのに役立ちます。s1 はローカル変数テーブルに格納され、s1 はポイントします。 to このオブジェクト空間 (s1 に格納されているオブジェクト空間のアドレスとして一時的に理解できます)。したがって、2 つの異なるオブジェクト空間である 2 つの新しいオブジェクトを作成しました。 ==s1 と s2 は異なる空間を指しているので、当然ながら判定は異なります。
2 番目の質問、上記の最初の点、各文字列は定数プール内の 1 つのコピーにのみ存在するため、str2 はこの定数プール文字列のアドレスを指し、str3 もこの定数プール文字列のアドレスを指します。 ==判定も当然同じです。
JVM は、
String 定数プール
を持つという点で、String
のストレージに関して少し特殊です。この定数プールには、String オブジェクトへの参照が含まれています。
String
的存储有一点特殊的地方在于有一块String常量池
。这个常量池里面存着对String对象的引用。
比如,
String s = "abc"
会先去String常量池
中查找有没有已经存在的引用,如果没有,声明的abc会直接生成一个String对象,并且会在String常量池
中存入一个引用指向这个String对象。之后直接声明的字符串同样也会遵循上面的步骤,所以第二次
String s2 = "abc"
从String常量池
中找到了一个引用指向第一次声明的字符串对象。而
new String("abc")
这样会直接在堆中创建新的对象,不会进入String常量池
。要把这样的对象引用放入常量池中就涉及另一个String类的方法intern()
,这个方法就是返回一个String对象的常量池引用。如果这个对象不在常量池中,就会把这个String对象放入常量池中并返回对应的对象引用。题主第一个截图的方法
たとえば、str2.intern() == str3.intern()
这样使用也会返回true
,调用intern()
返回的String常量池
String s = "abc"
は、まずString 定数プール
に移動して、既存の参照があるかどうかを確認します。存在しない場合は、宣言された abc が直接生成されます。 String オブジェクト、およびこの String オブジェクトを指す参照はString 定数プール
に保存されます。 🎜 🎜直後に宣言された文字列も上記の手順に従うため、2 回目にString s2 = "abc"
がString constant pool
から A を指す参照を見つけました。 -宣言された文字列オブジェクト。 🎜 🎜そして、new String("abc")
はヒープ内に新しいオブジェクトを直接作成し、String 定数プール
には入りません。このようなオブジェクト参照を定数プールに入れるには、String クラスの別のメソッドintern()
が必要です。このメソッドは String オブジェクトの定数プール参照を返します。このオブジェクトが定数プールにない場合、String オブジェクトは定数プールに入れられ、対応するオブジェクト参照が返されます。 🎜 🎜主題str2.intern() == str3.intern()
の最初のスクリーンショット メソッドもtrue
を返し、intern()
を呼び出します。返されたString constant pool
参照は同じです。 🎜Java の非組み込みデータ型はすべて参照です。
String s = new String("xx"); このメソッドはメモリ空間を作成し、参照 s がそれを指すようにします。
String s = "xx"; このメソッドは、参照 s が共有スペースを指すようにします。
new を使用して作成された場合、str2 と str3 は異なるメモリ空間を指すため、str2 と str3 は等しくありません。
文字列割り当てが直接使用される場合、str2 と str3 は同じメモリ空間を指すため、str2 と str3 は等しくなります。
str2.equals(str3) を使用して文字列の内容を比較できます。
1 つは定数プールに保存する方法、もう 1 つはヒープに新しいオブジェクトを作成する方法です
プロセスを理解するのに役立ちます。 Java には、覚えておくべきポイントがいくつかあります
1. すべての文字列は、不変の CONSTANT_String_info に対応する定数プールに生成されます。
2. 通常のオブジェクトはほとんどの場合ヒープ内に生成されます (もちろん、メソッド領域に生成されるクラス オブジェクトなどの特殊なオブジェクトもあります。これはさまざまな仮想マシンの実装に依存し、仮想マシンの仕様は異なります)必須)
3.= =この決定を行うとき、参照型の場合、最終分析はメモリ アドレスを比較することです。
さて、以上の概念ができました。最初の質問では、
String s1 = new String("aaa"); 新しいオブジェクトを作成するとき、jvm はヒープ上にオブジェクト空間を開くのに役立ちます。s1 はローカル変数テーブルに格納され、s1 はポイントします。 to このオブジェクト空間 (s1 に格納されているオブジェクト空間のアドレスとして一時的に理解できます)。したがって、2 つの異なるオブジェクト空間である 2 つの新しいオブジェクトを作成しました。 ==s1 と s2 は異なる空間を指しているので、当然ながら判定は異なります。
2 番目の質問、上記の最初の点、各文字列は定数プール内の 1 つのコピーにのみ存在するため、str2 はこの定数プール文字列のアドレスを指し、str3 もこの定数プール文字列のアドレスを指します。 ==判定も当然同じです。