Java';s intern()方法在运行时创建的字符串上运行
字符串s2=s1.concat(“ABC”);将在堆区域上创建一个新的字符串对象“ABCABC”。 字符串s3=s2.intern();应在字符串常量池中创建新的字符串对象 因为这是两个不同的对象,所以它们的引用不应该相等。但是似乎我错过了一些与intern()相关的重要内容。来自Java';s intern()方法在运行时创建的字符串上运行,java,string,constants,pool,Java,String,Constants,Pool,字符串s2=s1.concat(“ABC”);将在堆区域上创建一个新的字符串对象“ABCABC”。 字符串s3=s2.intern();应在字符串常量池中创建新的字符串对象 因为这是两个不同的对象,所以它们的引用不应该相等。但是似乎我错过了一些与intern()相关的重要内容。来自intern: 调用intern方法时,如果池中已包含一个字符串,该字符串等于equals(object)方法确定的该字符串对象,则返回池中的字符串。否则,此字符串对象将添加到池中,并返回对此字符串对象的引用 在调用i
intern
:
调用intern
方法时,如果池中已包含一个字符串,该字符串等于equals(object)
方法确定的该字符串对象,则返回池中的字符串。否则,此字符串对象将添加到池中,并返回对此字符串对象的引用
在调用intern
之前,字符串ABCABC
实际上已经在字符串池中了!根据上面的说明,如果字符串已经在池中,intern
只是从池中返回字符串,而不是在池中创建重复的字符串。这与从代码中的文本创建的字符串是同一个实例
“为什么绳子已经在游泳池里了?”我听到你问。这是因为字符串第一次出现在源代码中时没有添加到字符串池中。编译器收集源代码中的所有字符串文本,并将它们放入类文件中。当程序开始运行时,类文件中的所有字符串都会放入字符串池
要实际查看您期望的行为,您不能使用字符串literal“ABCABC”
。例如,您可以将其替换为“ABC”。concat(“ABC”)
:
在我看来,intern方法将字符串添加到字符串常量池中(如果没有字符串),然后返回字符串引用 因此,s4=“ABCABC”aready已存在字符串池来自: 返回字符串对象的规范表示形式。 最初为空的字符串池由类字符串私下维护。 调用intern方法时,如果池中已经包含一个等于equals(object)方法确定的该字符串对象的字符串,则返回池中的字符串否则,此字符串对象将添加到池中,并返回对此字符串对象的引用。 因此,对于任意两个字符串s和t,s.intern()==t.intern()为真当且仅当s.equals(t)为真时。 所有文字字符串和字符串值常量表达式都被插入。字符串文本在Java的第3.10.5节中定义™ 语言规范 因此,代码的内部字符串池的演变如下:
String s4 = "ABC".concat("ABC"); // this creates a new string
concat()在执行之前无法确定最终字符串的外观。字符串s2实际上会在堆区域中分配。考虑这个例子,类main {public static Valm main(String []ARGS){String S1=新字符串(“abc”);字符串S2= S1.CONTAT(“ABC”);字符串S3=“ABCABC”;Soal.Out.PrtLn(S2= S3);}如果s2已经在池中,那么为什么s2==s3会导致false。@ZabiKhan在答案发布后请不要更改您的问题,因为这会使答案无效。我已经回滚了您的编辑。@ZabiKhan,那么您是在问为什么
s2==s3
是真的?那么你的问题就如我所说的那样以重复的形式结束了。更正:编译时常量添加到池中的时间取决于实现。在此特定示例中,当s2==s3
为true
时,证明“ABCABC”
不在池中。否则,s1.concat(“ABC”)
的结果无法成为池成员。然后,当字符串s4=“ABCABC”当执行code>时,常量被解析为添加了字符串s3=s2.intern()的同一个对象代码>。因此,s3==s4
保证为true
,但在具有急切常量解析的环境中,s2==s3
将为false
。通常,“移动到常量池”和“留在堆中”是不合适的短语。所有对象都存储在堆中。运行时字符串池只是一些字符串的引用表。向池中添加字符串意味着添加引用。字符串对象本身保持不变。请重新访问问题。
String s4 = "ABC".concat("ABC"); // this creates a new string
public static void main(String[] args)
{
String s1 = new String("ABC");
// "ABC" generate a new string and add it to intern pool.
// new String("ABC") uses the already present ABC string to generate a new copy that is not present in the pool.
// s1 points to that string that is not present in the internal pool
String s2 = s1.concat("ABC");
// "ABC" is already present. s1.concat("ABC") creates a new string ABCABC that is added to the internal pool. s2 point to that string
String s3 = s2.intern();
// s2.intern() returns a pointer to ABCABC that is already present in the internal pool. s3 points to that string
System.out.println(s2 == s3);
// Prints true because ABCABC present in the internal pool is pointed by both s2 and s3.
String s4 = "ABCABC";
// ABCABC is already present in the internal pool. s4 points to that string
System.out.println(s3 == s4);
// Prints true because all s2, s3, s4 points to the same instance ABCABC present in the internal pool.
}