Java字符串的创建和字符串常量池

12

当使用关键字new创建字符串时,它将使用一个接受字符串字面量的构造函数创建一个新的字符串对象。我想知道在调用字符串构造函数之前,字面值是否会存储在常量池中。

我问这个问题的原因是,在《OCA Java SE 7程序员I认证指南》中,Mala Gupta写道:

public static void main(String[] args)
{
    String summer  = new String("Summer");   //Line 1: The code creates a new String object with the value "Summer". This object is not placed in the String constant pool.
    String summer2 = "Summer"                //Line 2: The code creates a new String object with the value "Summer" and places it in the String constant pool.
}

她在第一行说通过new创建的String对象不会存储在常量池中。这没问题,但不清楚的是在构造函数中放入的字面量"Summer"是否被存储在常量池中。

在第二行中,她说将"Summer"分配给summer2将其存储在常量池中,这意味着第一行的字面量并没有放置在常量池中。

我的问题

  1. 第1行:构造函数中的字面量"Summer"是否在调用String构造函数之前放置在常量池中?
  2. 第2行:在第2行时,"Summer"是否已经存在于常量池中,还是在此行插入?
  3. 第2行:作者在说"Summer"在第2行插入到池中时是错的吗?

她在第一行中指出,使用new创建的String对象不会被存储在常量池中。这没问题,但是不清楚的是构造函数中放入的字面量"Summer"是否被放置在常量池中。

在第二行中,她指出将"Summer"赋值给summer2会将其存储在常量池中,这意味着第一行的字面量没有被放置在常量池中。

我的问题

  1. 第1行:构造函数中的字面量"Summer"是否在调用String构造函数之前就已经被放置在常量池中?
  2. 第2行:在第2行时,"Summer"是否已经存在于常量池中,还是在此行插入?
  3. 第2行:作者在说"Summer"在第2行插入到池中时是错的吗?

https://dev59.com/JWYq5IYBdhLWcg3w2EFi - ZaoTaoBao
请看:https://dev59.com/vWgt5IYBdhLWcg3w8h01 - naveejr
@naveejr 不是重复问题,但肯定有所帮助 :) 谢谢。 - Adam
4个回答

10

简而言之,不带任何混淆,

你写道,

   String summer  = new String("Summer");   //Line 1: The code creates a new String object with the value "Summer". This object is not placed in the String constant pool.

那是错误的。特别是评论部分 This object is not placed in the String constant pool.

字符串字面值 "Summer" 现在已经在常量池中了。而对象 summer 创建在堆上。

构造函数中的字面值 "Summer" 是否在调用 String 构造函数之前放入常量池中?

是的。它作为一个字符串字面值进入到常量池中。

在第2行时,"Summer"是否已经存在于常量池中,还是在这一行插入?

不是。因为您没有对其进行内部化操作,所以有两个字面值存在。(了解更多关于字符串内部化)

作者在说“Summer”在第2行被放入常量池时是错的吗?

其他内容都是正确的。

为了记忆起见,我们甚至可以简单地说,位于 "" 之间的所有内容都会进入常量池,无论使用它的位置在哪里。


如果在第一行插入"Summer"并且它已经存在于第二行,那么作者不是错了吗? - Adam
@Adam 如果作者说它没有被插入到池中,而你使用的是正确的方式,那么作者是错误的。你在第一行的评论中说它没有被放置。在你的问题列表中,你说它被放置在池中。你能再次交叉检查并发表评论吗?我有点困惑。 - Suresh Atta
@sᴜʀᴇsʜ 代码中的注释是作者编写的。我的问题是,“如果第1行的字面插入到池中,那么作者说它插入到第2行是错误的吗?”希望这更清晰 :) - Adam
如果作者说它只插入在第2行,那是错误的。它被插入到了两行。 - Suresh Atta
@sᴜʀᴇsʜᴀᴛᴛᴀ - 你能通过代码证明吗?我被问到了同样的问题,我回答了和你一样的答案,但是那个问问题的人说 - 你能证明吗 - TheLostMind
显示剩余2条评论

1

Code 1 - Line 1: 构造函数中的文本"Summer"是否在调用String构造函数之前被放置在常量池中?

是的。JLS规定:

这是因为字符串字面量 - 或者更一般地说,是常量表达式(§15.28)的值的字符串 - 被“interned”以共享唯一实例,使用方法String.intern。

由于该字符串是字面量(因此是常量表达式的值),它将被插入。但是,分配给变量summer的对象不是同一个字面量,而是明确创建的新字符串对象,用于复制该字面量的值。

Code 1 - Line 2: "Summer"已经存在于第2行的常量池中还是在此行插入?

如上所述,它已经被插入。

Code 2 - Line 2: 作者在说"Summer"在第2行被放置在池中时是错误的吗?

不是 - 尽管我同意措辞可能可以更清晰。


-1
**Code 1 - Line 1: Does the literal "Hello" in the constructor get placed in the constant pool before the String constructor is called?**

是的,因为构造函数用于实例化对象。

****Code 1 - Line 2: Does "Hello" already exist in the pool at line 2 or is it inserted at this line?****

**它已经在那里了**。它不是由这行插入的。您可以通过以下方式进行检查。

       String s=new String("hello");
String s1=s.intern();
String s2 = new String("hello");
String s3= s2.intern();

if (s1==s3)
{
System.out.println("true");
} if (s==s2)
{System.out.println("false");}

代码2 - 第2行:作者在第2行说“Summer”被放置在池中时是错误的吗?

不是。因为代码2-第1行已经将“Summer”放置在常量池中,所以它不会再次被放置。


我知道有些人会对这个答案进行负面评价。字面值将字符串直接放入常量池(字符串s)中。而字符串s1也会创建一个对象,并检查常量池中是否存在字符串“hello”。由于“hello”之前已经通过字面方法放入常量池中,所以将打印true,我们就知道它在那里了。 - Deepanshu J bedi
2
完全不是这样。new String()总是会创建一个新的对象,所以它输出的是false - Keppil
我忘记了intern方法。谢谢你们的踩。 - Deepanshu J bedi

-3
    public static void main(String[] args)
    {
        String summer  = new String("Summer");   //Line 1: The code creates a new String object 
}

值为Summer。该对象未放置在字符串常量池中。

这个说法是错误的。上述代码将创建两个对象,一个在常量池中,另一个在堆中。无论是否在构造函数内部,每当你写"ABC"时,它都会进入常量池。

证明如下:

String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
String s4 = new String("Rakesh");
String s5 = new String("Rakesh").intern();

if ( s1 == s2 ){
    System.out.println("s1 and s2 are same");  // 1.
}

if ( s1 == s3 ){
    System.out.println("s1 and s3 are same" );  // 2.
}

if ( s1 == s4 ){
    System.out.println("s1 and s4 are same" );  // 3.
}

if ( s1 == s5 ){
    System.out.println("s1 and s5 are same" );  // 4.
}will return:

s1 and s2 are same
s1 and s3 are same
s1 and s5 are same

4
不,他将无法从上面的代码中得到他想要的答案。而且,“我认为一旦你运行以上代码,你将回答所有三个问题”是一个非常糟糕的回答方式。 - TheLostMind
抱歉,我的错误。 - Arun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接