3

我正在阅读一些关于 Java 最佳实践的建议,我得到了以下让我感到好奇的想法

此外,无论何时你想实例化一个 String 对象,都不要使用它的构造函数,而总是直接实例化它。

例如:

//slow instantiation
String slow = new String("Yet another string object");

//fast instantiation
String fast = "Yet another string object";

为什么是这样?'fast' 不会调用默认的字符串构造函数吗?

4

2 回答 2

9

当您使用时,new您会得到一个新的字符串对象,但如果您使用字符串文字请参见此处

在计算机科学中,字符串实习是一种仅存储每个不同字符串值的副本的方法,该副本必须是不可变的。驻留字符串使某些字符串处理任务更节省时间或空间,但代价是创建或驻留字符串时需要更多时间。不同的值存储在字符串实习池中。每个字符串的单个副本称为其“实习生”,通常由字符串类的方法查找,例如 Java 中的 String.intern()。Java 中的所有编译时常量字符串都使用此方法自动进行实习。

如果你这样做:

String a = "foo";
String b = "foo";

那么a==b真的

只有在没有被实习的情况下才会创建一个字符串。一个对象将在第一次创建,并将存储在一个称为字符串常量池的地方。

但是使用newwhich 将为每个字符串创建一个不同的对象,将输出false

String a = new String("foo");
String b = new String("foo");

现在a==b的。

因此,当使用文字时,它更容易阅读,而且编译器更容易进行优化。所以..尽可能使用它。

于 2013-03-26T19:57:55.737 回答
1

JVM 维护一个String用于优化的文字池。当您String使用构造函数创建一个时,

String s1 = new String("foo");

创建了一个新String对象,并将文字"foo"添加到池中。在此之后,无论何时您"foo"在代码中使用,都会"foo"引用池中的项目并且不会创建新对象。由于String是不可变的,因此不会产生任何问题。

因此,当您String使用“快捷方式”创建一个时:

String s2 = "foo"

JVM查看池,如果"foo"已经存在,它将s2引用池中的项目。

这是可能影响性能的一个主要区别:构造函数总是创建一个对象,如果池中尚不存在该字面量,则将其添加到池中。快捷方式引用池中的项目,并且仅当 liuteral 不在池中时才创建新对象。

于 2013-03-26T20:05:07.750 回答