0

有一个关于 Java 中 Stringz 实例池的简单问题

如果我有这样的情况:场景1:

String s1 = "aaa";  
String s2 = new String("aaa");  

然后翻转场景2:

String s1 = new String("aaa");  
String s2 = "aaa";  

在每种情况下 - 在字符串池和堆中创建了多少个对象?我假设两者都会创建相同数量的对象(2 个对象 - 在字符串池中的每个场景中,两条线都有一个“aaa”,而新的运算符则有一个)。我在 iview 中被告知这是不正确的 - 我很好奇我的理解有什么问题?

4

2 回答 2

1

字面量的字符串"aaa"是在加载类时创建和池化的,所以当你的两行代码被执行时,只会创建一个新的字符串。

需要明确的是:这两个示例在执行时都只创建一个新的 String 对象。第一次使用包含字符串“aaa”的类时会创建文字。

class FooBar{
  void foo(){
    String s1 = "aaa";//the literal already exists  
    String s2 = new String("aaa");//creates string for s2 
  }
  void bar(){
    String s1 = new String("aaa"); //creates string for s1 
    String s2 = "aaa";//the literal already exists  
  }
}

class Test{

    public void main(String... args){
      ...
      //first time class FooBar used in program, class with literals loaded
      FooBar fb = new FooBar();
      //creates one string object, the literal is already loaded
      fb.bar();
      //also creates one string object, the literal is already loaded
      fb.foo();
    }
}
于 2012-04-06T15:35:14.047 回答
1

正如您在采访中所说的那样,无论哪种情况,答案都是堆中的 1 个实例和字符串池中的 1 个。

字符串可以驻留有两个空间:堆和存储内部字符串的永久代。

String 构造函数在堆中创建一个 String。字符串文字是在永久代的字符串池中创建的。堆中的字符串可以通过实习字符串的方法移动到字符串池String.intern()(即确定对池中相等字符串的引用,或者在那里创建相等的字符串,如果还没有的话)并返回对实习字符串。

编辑:要检查我的回答,请System.out.println(s1 == s2);在每个示例中添加第三行。在这两种情况下都会打印 false,证明两个对象具有不同的内存地址。

于 2012-04-06T15:51:59.930 回答