当前位置: 首页 > 知识库问答 >
问题:

字符串常量池

傅茂实
2023-03-14

如这些问题中所述:问题1

String s = "abc"; 

在以下情况下,JVM将创建一个新的字符串对象,而不是使用字符串池中的现有对象:

String s = new String("abc");

然而,在阅读了下面两个类似的陈述之后,我有一个疑问。

  • 从SCJP准备书:

当编译器遇到字符串文字时,它会检查池中是否已经存在相同的字符串。如果找到匹配项,对新文本的引用将指向现有的String,并且不会创建新的String文本对象。

  • 来自JavaRanch:

在本例中,由于关键字“new”,我们最终的行为实际上略有不同在这种情况下,对字符串文本的引用仍然放在常量表(字符串文本池)中,但是,当您使用关键字“new”时,JVM必须在运行时创建一个新的字符串对象,而不是使用常量表中的字符串对象。

因此,如果我们在使用“new”并基于上述定义创建对象时,也将引用放入非池内存和池内存中。当我们执行此操作时,JVM是否也应该返回相同的引用

String one = new String("test");
String two = "test";

System.out.println(one.equals(two)); // true
System.out.println(one == two);      // false

因为当声明字符串literalstringthree=“test” 它是否已存在于池中?因此应该返回相同的引用并打印true吗?或者前面的语句是否意味着它们将放在池内存中,但在使用new运算符时只是跳过?


共有3个答案

祁乐邦
2023-03-14

你的问题:

因此,如果我们在使用“new”并基于上述定义创建对象时,也将引用放入非池内存和池内存中。当我们执行此操作时,JVM是否也应该返回相同的引用

Ans:当您使用new关键字创建新的string对象时,生成的地址将是堆地址,而不是字符串常量池地址。两个地址都不一样。

问题:

String one = new String("test");
String two = "test";

System.out.println(one.equals(two)); // true
System.out.println(one == two);      // false

前面的语句是否意味着它们将放在池内存中,但在使用新运算符时只是跳过?

回答:是的,你的假设是正确的。当程序员使用new关键字时,JVM将简单地忽略字符串常量池,并在堆中创建一个新副本。因此,两个地址不相同。

邴墨竹
2023-03-14
    //Creates a new object even if one exists in the pool
    String s1 = new String("Tendulkar");

    // makes a new object string and then the reference is available to the pool
    String s2 = s1.intern();

    //this object is not created but references the address present in the pool
    String s3 = "Tendulkar";

    System.out.print(s1==s2); // results in false
    System.out.print(s2==s3); //very very true !!!
孔安福
2023-03-14

也许这将有助于你的理解:

String literal = "test";
String one = new String(literal);
String two = "test";

System.out.println(literal == two); //true
System.out.println(one == two); //false

在您发布的示例中:

String one = new String("test");
String two = "test";

由于内部原因,传递给构造函数的引用String(String)与引用two具有相同的值。但是,字符串本身(由这两个引用引用)用于构造分配给referenceone的新对象。

在本例中,使用值“test”创建了两个String:一个在常量池中维护并在表达式中使用文本“test”时引用,另一个由“new”操作符创建并分配给引用one

也许你对这句话感到困惑:

当编译器遇到字符串文字时,它会检查池中是否已经存在相同的字符串。

请注意,这可能会更清楚地表述为:

当编译器遇到字符串文字时,它会检查池中是否已经存在相同的字符串。

只有当字符串被显式插入或通过类使用文本进行插入时,才会将其放入池中。例如,如果您有以下情况:

String te = "te";
String st = "st";

String test = new String(te) + new String(st);

然后,虽然字符串将与值test一起存在,但所述字符串将不存在于池中,因为文本“test”从未出现过。

 类似资料:
  • 当使用关键字 new 创建字符串时,它使用采用 String 文本的构造函数创建新的 String 对象。我想知道在调用 String 构造函数之前,文本是否存储在常量池中。 我这么问的原因是,在《OCA Java SE 7程序员I认证指南》中,Mala Gupta写道: 她在第一行表示,new创建的String对象不会存储在常量池中。这很好,但不清楚的是,第一行构造函数中的字面“Summer”是

  • 本文向大家介绍字符型常量和字符串常量的区别相关面试题,主要包含被问及字符型常量和字符串常量的区别时的应答技巧和注意事项,需要的朋友参考一下 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的若干个字符 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置) 占内存大小:字符常量只占2个字节; 字符串常量占

  • 首先,考虑这个例子: 我期望什么:因为“123”是一个< code>const char*,我期望这些字符串的地址(就像其中一个答案所说的)被比较。 …因为和将只比较这些字符串的基址。不是字符串本身的内容。 但输出仍然是。好吧,我们实际上不知道如何比较两个prvalue对象的地址(或者至少我不明白会怎么做)。所以让我们将这些字符串声明为变量,看看会发生什么: 输出仍然是 。所以字符串不会衰减吗?或

  • 问题内容: 这与Java字符串常量池有关。在我的一个程序中,我正在解密数据库的密码并将其存储在字符串中。我听说Java字符串将存储在Constant池中,并且不会被VM重新启动或加载了String Quits的ClassLoader破坏。 如果是这种情况,我的密码将存储在字符串池中。我非常关心这个问题。还有其他方法可以销毁这些文字或我可以做的其他任何事情。 请对此提出建议, 问候,阳光明媚。 问题

  • 本文向大家介绍使用VBA字符串常量,包括了使用VBA字符串常量的使用技巧和注意事项,需要的朋友参考一下 示例 VBA为特殊字符定义了许多字符串常量,例如: vbCr:回车符,与C样式语言中的“ \ r”相同。 vbLf:换行符'与C样式语言中的“ \ n”相同。 vbCrLf:回车和换行(Windows中的换行符) vbTab:制表符 vbNullString:空字符串,例如“” 您可以将这些常量

  • 问题内容: 在C ++中,创建多行字符串的最佳规范方法是创建相邻字符串,并让编译器在编译时将它们连接起来,如下所示: 在Java中,我唯一知道的方法是串联: 问题是,这是在运行时生成单个字符串,还是Java实际上也在编译时进行连接?出现此问题的原因是由于以下行为: 问题答案: String s3 = “a”; s3 += “bc”; 与: 因此,它创建了一个新实例。 您甚至可以尝试: