【发布时间】:2011-02-26 17:23:58
【问题描述】:
可能重复:
What is the purpose of the expression “new String(…)” in Java?
嗨,
1) 这两种说法有什么区别:
String s1 = "abc";
和
String s1 = new String("abc")
2) 因为我没有在第一个语句中使用 new,所以如何创建字符串对象
谢谢
【问题讨论】:
可能重复:
What is the purpose of the expression “new String(…)” in Java?
嗨,
1) 这两种说法有什么区别:
String s1 = "abc";
和
String s1 = new String("abc")
2) 因为我没有在第一个语句中使用 new,所以如何创建字符串对象
谢谢
【问题讨论】:
第一个将使用将在代码中编译的固定字符串。第二个变体使用固定的字符串并通过复制字符来创建一个新的字符串。这实际上在内存中创建了一个新的单独对象并且没有必要,因为字符串是不可变的。更多信息可以阅读this thread。
具有内部化字符串的主要优点是性能更好(例如通过缓存等)。
作为程序员,创建新字符串并没有真正的好处,除非您通过以下示例:
String sentence = "Lorem ipsum dolor sit amet";
String word = sentence.substring(5);
现在单词有对句子的引用(子字符串不复制字符)。这在使用句子时很有效,但是当这个句子被丢弃时,您使用的内存比需要的多得多。在这种情况下,可以创建一个新字符串:
word = new String(word);
【讨论】:
String(String s) 构造函数不会创建新的 char 数组但也保留引用。就像substring(int a, int b),内部调用new String(int start, int length, char[] chars)
String(String s) 构造函数会进行复制。来自 javadoc:Initializes a newly created {@code String} object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string
在第一种情况下,编译器知道字符串 s1 的值。因此,所有具有相同值的字符串将使用相同的内存位置:
String s1 = "abc";
String s2 = "abc";
虽然有两个 String 引用(s1 和 s2),但内存中只有一个“abc”序列。不需要new 运算符,因为编译器会完成这项工作。
在第二种情况下,编译器不执行字符串值的评估。因此,该句子将在运行时生成一个新的 String 实例:
String s1 = "abc";
String s2 = new String("abc");
第 1 行中的常量“abc”与第 2 行中的常量“abc”引用了相同的内存。但第 2 行的最终效果是创建了一个新的 String 实例。
【讨论】: