1

有两种方法可以创建 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[] 对象。

那么substrand会发生什么substr2?我们可以将这些东西与构造函数联系起来,因为偏移量是在构造函数内部生成的。

4

3 回答 3

3

来自 JLS §3.10.5。字符串文字

字符串文字是对类实例的引用String(第 4.3.1 节、第 4.3.3 节)。

此外,字符串字面量始终指代同一个 class 实例String。这是因为字符串文字 - 或者更一般地说,作为常量表达式值的字符串(第 15.28 节) - 是“内部的”,以便使用方法共享唯一实例String.intern

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

要确保在堆内存substrsubstr2是相同类型的操作和相同的行为。

是的,它们是完全一样的操作。

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

这是未指定的。您所描述的是旧版本的 Oracle JDK 是如何工作的。当前版本不再这样做了substring()现在复制字符。此更改是在 Java 7u6 中进行的。

于 2013-04-13T09:55:28.197 回答
2

创建任何对象时都会调用构造函数。

的情况下String str2 = "World";,jvm会先在字符串池中搜索"world"字符串。仅当池中不存在此文字时才会调用构造函数,否则它将返回现有对象。

于 2013-04-13T09:54:01.623 回答
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()构造函数。然后“Step out”构造函数,“Step over”到下一行并再次“Step into”。您应该String()再次在构造函数中。

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

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

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

于 2013-04-13T09:58:20.807 回答