字符串对象创建及其构造函数

时间:2013-04-13 09:50:35

标签: java

有两种方法可以创建String对象。

String str = new String("Java");
String str2 = "Java";

我知道在第一种情况下肯定会调用构造函数。但不知道第二个。 是否会调用构造函数?

String substr = new String(str.substring(2,str.length));  // str is new object
String substr2 = new String(str2.substring(2,str2.length)); //str2 is not with new keyword

希望确保substrsubstr2在堆内存中具有相同的操作和相同的行为。

我知道String.substring()根本不会创建新对象,而是使用具有不同偏移量的先前char []对象。

那么substrsubstr2会发生什么?我们可以将这些东西与构造函数联系起来,因为在构造函数中生成了偏移量。

3 个答案:

答案 0 :(得分:3)

来自JLS §3.10.5. String Literals

  

字符串文字是对类String的实例的引用(§4.3.1,§4.3.3)。

     

此外,字符串文字始终引用类String的同一实例。这是因为字符串文字 - 或者更常见的是作为常量表达式(第15.28节)的值的字符串 - 被“实现”以便使用方法String.intern共享唯一实例。

因此,"Java"指的是String个对象。此外,由相同字符组成的任何字符串文字都将引用相同的String对象。但是,如何以及何时构造此对象是未指定的。

  

希望确保substrsubstr2在堆内存中具有相同的操作和相同的行为。

是的,它们完全是同一种操作。

  

我知道String.substring()根本不会创建新对象,而是使用具有不同偏移量的先前char []对象。

这是未指定的。您所描述的是旧版本的Oracle JDK的工作原理。当前版本don't do that anymoresubstring()现在复制字符。此更改是在Java 7u6中进行的。

答案 1 :(得分:2)

在创建任何对象时调用

构造函数。

如果是String str2 = "World";,jvm将首先在字符串池中搜索字符串"world"。只有在池中不存在该文字时才会调用构造函数,否则它将返回现有对象。

答案 2 :(得分:0)

应始终调用构造函数。 为了自己找出调试这个应用程序:

public static void main(String[] args) {
  String str = new String("Java"); // <-- breakpoint here
  String str2 = "World";
  String str3 = "Java"; // (1)
  String str4 = new String("Java"); // (2)

  System.out.println(str + " " + str2 + " " + str3 + " " + str4);
}

在第一行(String str = new...)和“Step into”设置断点以进入String()构造函数。然后“走出”构造函数,“跳过”到下一行,然后再“步入”。你应该再次进入String()构造函数。

1:至于str3,它应该来自池,即if (str3 == str)将是true

2:但str4将是一个新实例,即if (str4 == str || str4 == str3)将是false。请参阅String API

让我们知道你发现了什么: - )