字符串是 Java 中的对象,那么为什么我们不使用“new”来创建它们呢?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2009228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Strings are objects in Java, so why don't we use 'new' to create them?
提问by giri
We normally create objects using the new
keyword, like:
我们通常使用new
关键字创建对象,例如:
Object obj = new Object();
Strings are objects, yet we do not use new
to create them:
字符串是对象,但我们不用new
来创建它们:
String str = "Hello World";
Why is this? Can I make a String with new
?
为什么是这样?我可以用 做一个字符串new
吗?
采纳答案by danben
In addition to what was already said, String literals[ie, Strings like "abcd"
but not like new String("abcd")
] in Java are interned - this means that every time you refer to "abcd", you get a reference to a single String
instance, rather than a new one each time. So you will have:
除了已经说过的内容之外,Java 中的字符串字面量[即 Strings like "abcd"
but not like new String("abcd")
] 是 intern - 这意味着每次引用“abcd”时,您都会获得对单个String
实例的引用,而不是一个新实例每一次。所以你将拥有:
String a = "abcd";
String b = "abcd";
a == b; //True
but if you had
但如果你有
String a = new String("abcd");
String b = new String("abcd");
then it's possible to have
那么有可能有
a == b; // False
(and in case anyone needs reminding, always use .equals()
to compare Strings; ==
tests for physical equality).
(如果有人需要提醒,请始终用于.equals()
比较字符串;==
测试物理相等性)。
Interning String literals is good because they are often used more than once. For example, consider the (contrived) code:
实习字符串文字很好,因为它们经常被使用不止一次。例如,考虑(人为的)代码:
for (int i = 0; i < 10; i++) {
System.out.println("Next iteration");
}
If we didn't have interning of Strings, "Next iteration" would need to be instantiated 10 times, whereas now it will only be instantiated once.
如果我们没有字符串的实习,“下一次迭代”将需要被实例化 10 次,而现在它只会被实例化一次。
回答by Malfist
回答by Andreas Dolk
Feel free to create a new String with
随意创建一个新的字符串
String s = new String("I'm a new String");
The usual notation s = "new String";
is more or less a convenient shortcut - which should be used for performance reasons except for those pretty rare cases, where you reallyneed Strings that qualify for the equation
通常的符号s = "new String";
或多或少是一种方便的快捷方式 - 出于性能原因应该使用它,除了那些非常罕见的情况,在这种情况下,您确实需要符合等式的字符串
(string1.equals(string2)) && !(string1 == string2)
EDIT
编辑
In response to the comment: this was notintended to be an advise but just an only a direct response to the questioners thesis, that we do not use the 'new' keywordfor Strings, which simply isn't true. Hope this edit (including the above) clarifies this a bit. BTW - there's a couple of good and much better answers to the above question on SO.
回应评论:这不是一个建议,而只是对提问者论文的直接回应,我们不对字符串使用“new”关键字,这根本不是真的。希望这个编辑(包括上面的)澄清了这一点。顺便说一句 - 上面关于 SO 的问题有几个很好的更好的答案。
回答by Brian Agnew
String is subject to a couple of optimisations (for want of a better phrase). Note that String also has operator overloading (for the + operator) - unlike other objects. So it's very much a special case.
字符串需要进行一些优化(因为需要更好的短语)。请注意,String 还具有运算符重载(对于 + 运算符)——与其他对象不同。所以这是一个非常特殊的情况。
回答by Seva Alekseyev
Syntactic sugar. The
语法糖。这
String s = new String("ABC");
syntax is still available.
语法仍然可用。
回答by Peter ?tibrany
You can still use new String("string")
, but it would be harder to create new strings without string literals ... you would have to use character arrays or bytes :-) String literals have one additional property: all same string literals from any class point to same string instance (they are interned).
您仍然可以使用new String("string")
,但是创建没有字符串文字的新字符串会更困难……您将不得不使用字符数组或字节 :-) 字符串文字有一个附加属性:来自任何类的所有相同字符串文字都指向同一个字符串实例(他们被实习)。
回答by Jamie McCrindle
Strings are "special" objects in Java. The Java designers wisely decided that Strings are used so often that they needed their own syntax as well as a caching strategy. When you declare a string by saying:
字符串是 Java 中的“特殊”对象。Java 设计者明智地决定经常使用字符串,因此他们需要自己的语法和缓存策略。当您通过以下语句声明字符串时:
String myString = "something";
myString is a reference to String object with a value of "something". If you later declare:
myString 是对值为“something”的 String 对象的引用。如果您稍后声明:
String myOtherString = "something";
Java is smart enough to work out that myString and myOtherString are the same and will store them in a global String table as the same object. It relies on the fact that you can't modify Strings to do this. This lowers the amount of memory required and can make comparisons faster.
Java 足够聪明,可以计算出 myString 和 myOtherString 是相同的,并将它们作为同一个对象存储在全局字符串表中。它依赖于您无法修改字符串来执行此操作的事实。这降低了所需的内存量,并且可以更快地进行比较。
If, instead, you write
相反,如果你写
String myOtherString = new String("something");
Java will create a brand new object for you, distinct from the myString object.
Java 将为您创建一个全新的对象,与 myString 对象不同。
回答by brianegge
In Java, Strings are a special case, with many rules that apply only to Strings. The double quotes causes the compiler to create a String object. Since String objects are immutable, this allows the compiler to intern multiple strings, and build a larger string pool. Two identical String constants will always have the same object reference. If you don't want this to be the case, then you can use new String(""), and that will create a String object at runtime. The intern() method used to be common, to cause dynamically created strings to be checked against the string lookup table. Once a string in interned, the object reference will point to the canonical String instance.
在 Java 中,字符串是一种特殊情况,许多规则仅适用于字符串。双引号使编译器创建一个 String 对象。由于 String 对象是不可变的,这允许编译器对多个字符串进行实习,并构建一个更大的字符串池。两个相同的 String 常量将始终具有相同的对象引用。如果您不希望出现这种情况,那么您可以使用 new String(""),这将在运行时创建一个 String 对象。intern() 方法曾经很常见,用于根据字符串查找表检查动态创建的字符串。一旦字符串被插入,对象引用将指向规范的 String 实例。
String a = "foo";
String b = "foo";
System.out.println(a == b); // true
String c = new String(a);
System.out.println(a == c); // false
c = c.intern();
System.out.println(a == c); // true
When the classloader loads a class, all String constants are added to the String pool.
当类加载器加载一个类时,所有的 String 常量都被添加到 String 池中。
回答by mP.
There's almost no need to new a string as the literal (the characters in quotes) is already a String object created when the host class is loaded. It is perfectly legal to invoke methods on a literal and don, the main distinction is the convenience provided by literals. It would be a major pain and waste of tine if we had to create an array of chars and fill it char by char and them doing a new String(char array).
几乎不需要新的字符串,因为文字(引号中的字符)已经是加载宿主类时创建的 String 对象。在文字和 don 上调用方法是完全合法的,主要区别在于文字提供的便利。如果我们必须创建一个字符数组并逐个字符填充它,然后他们做一个新的字符串(字符数组),那将是一个巨大的痛苦和浪费。
回答by lavina
The literal pool contains any Strings that were created without using the keyword new
.
文字池包含所有未使用关键字创建的字符串new
。
There is a difference : String without new reference is stored in String literal pool and String with new says that they are in heap memory.
有一个区别:没有新引用的字符串存储在字符串文字池中,而带有新引用的字符串表示它们在堆内存中。
String with new are elsewhere in memory just like any other object.
带有 new 的字符串就像任何其他对象一样在内存中的其他地方。