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

时间:2014-07-23 12:30:54

标签: java string string-literals

使用关键字 new 创建String时,它会使用带有String文字的构造函数创建一个新的String对象。我想知道在调用String构造函数之前文字是否存储在常量池中。

我问的原因是,在“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”是否为。

在第二行,她说“夏天”到 summer2 的分配将它存储在常量池中,这意味着第一行的文字没有放在池中。

我的问题

  1. 第1行:在调用String构造函数之前,构造函数中的文字“Summer”是否放在常量池中?
  2. 第2行:第2行中的游泳池中是否已存在“夏季”,或者是否已插入此行?
  3. 第2行:如果作者在第2行中将“Summer”插入池中,是否有错误?

4 个答案:

答案 0 :(得分: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

  

在调用String构造函数之前,构造函数中的文字“Summer”是否放在常量池中?

是。它会转到池中,因为它是一个字符串文字。

  

第2行的池中是否已经存在“Summer”,或者它是否插入此行?

没有。因为你没有实习,所以有两个文字。 (阅读更多关于String interning

的信息
  

当她说“夏天”放在第2行的游泳池时,作者是否错了?

该行的其他方面是正确的。

为了纪念,我们甚至可以简单地说""之间的所有内容都会进入池中,无论它在何处使用。

答案 1 :(得分:1)

  

代码1 - 第1行:在调用String构造函数之前,构造函数中的文字“Summer”是否放在常量池中?

是。 JLS声明:

  

这是因为字符串文字 - 或者更常见的是字符串是常量表达式(第15.28节)的值 - 是“实习”,以便使用String方法共享唯一实例。实习生。

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

  

代码1 - 第2行:第2行的池中是否已经存在“Summer”,或者它是否插入此行?

如上所述,它已经插入。

  

代码2 - 第2行:当她说“夏天”放在第2行的游泳池时,作者是否错了?

不 - 虽然我同意措辞可能更清楚。

答案 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行的游泳池中,是否是错误的?

即可。夏天不会被放置在恒定的游泳池,因为它已经存在,code2-line1将在那里放置“夏天”。

答案 3 :(得分:-3)

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

,值为Summer。此对象未放置在String常量池中。

这种说法是错误的。 ABove行将创建2个对象,一个在Constant池中,另一个在堆中。无论何时你都会写" 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