Java 字符串对象和字符串文字的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3297867/
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
Difference between string object and string literal
提问by user395617
What is the difference between
之间有什么区别
String str = new String("abc");
and
和
String str = "abc";
回答by Mark Byers
When you use a string literal the string can be interned, but when you use new String("...")
you get a new string object.
当您使用字符串文字时,字符串可以被interned,但是当您使用时,您将new String("...")
获得一个新的字符串对象。
In this example both string literals refer the same object:
在这个例子中,两个字符串字面量都指向同一个对象:
String a = "abc";
String b = "abc";
System.out.println(a == b); // true
Here, 2 different objects are created and they have different references:
在这里,创建了 2 个不同的对象,它们具有不同的引用:
String c = new String("abc");
String d = new String("abc");
System.out.println(c == d); // false
In general, you should use the string literal notation when possible. It is easier to read and it gives the compiler a chance to optimizeyour code.
通常,您应该尽可能使用字符串文字表示法。它更易于阅读,并且为编译器提供了优化代码的机会。
回答by sushil bharwani
In the first case, there are two objects created.
在第一种情况下,创建了两个对象。
In the second case, it's just one.
在第二种情况下,它只是一种。
Although both ways str
is referring to "abc"
.
虽然这两种方式str
都是指"abc"
.
回答by Micha? Niklas
According to String class documentationthey are equivalent.
根据String 类文档,它们是等效的。
Documentation for String(String original)
also says that: Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.
文档String(String original)
还说:除非需要原始的显式副本,否则不需要使用此构造函数,因为字符串是不可变的。
Look for other responses, because it seems that Java documentation is misleading :(
寻找其他响应,因为 Java 文档似乎具有误导性:(
回答by krock
"abc"
is a literal String.
"abc"
是一个文字字符串。
In Java, these literal strings are pooled internally and the same String instance of "abc"
is used where ever you have that string literal declared in your code. So "abc" == "abc"
will always be true as they are both the same String instance.
在 Java 中,这些文字字符串在内部进行池化,并且"abc"
在代码中声明该字符串文字的任何地方都使用相同的 String 实例。所以"abc" == "abc"
总是如此,因为它们都是同一个 String 实例。
Using the String.intern()
method you can add any string you like to the internally pooled strings, these will be kept in memory until java exits.
使用该String.intern()
方法,您可以将任何您喜欢的字符串添加到内部池字符串中,这些字符串将保存在内存中,直到 java 退出。
On the other hand, using new String("abc")
will create a new string object in memory, which is logically the same as the "abc"
literal.
"abc" == new String("abc")
will always be false, as although they are logically equal they refer to different instances.
另一方面, usingnew String("abc")
将在内存中创建一个新的字符串对象,它在逻辑上与"abc"
文字相同。
"abc" == new String("abc")
将始终为假,尽管它们在逻辑上是相等的,但它们指的是不同的实例。
Wrapping a String constructor around a string literal is of no value, it just needlessly uses more memory than it needs to.
将 String 构造函数包裹在字符串文字周围是没有价值的,它只是不必要地使用了比它需要的更多的内存。
回答by Andreas Dolk
A String literalis a Java language concept. This is a String literal:
一个字符串文字是Java语言的概念。这是一个字符串文字:
"a String literal"
A String objectis an individual instance of the java.lang.String
class.
甲字符串对象是的单个实例java.lang.String
的类。
String s1 = "abcde";
String s2 = new String("abcde");
String s3 = "abcde";
All are valid, but have a slight difference. s1
will refer to an internedString object. This means, that the character sequence "abcde"
will be stored at a central place, and whenever the same literal "abcde"
is used again, the JVM will not create a new String object but use the reference of the cachedString.
都是有效的,但略有不同。s1
将引用一个实习字符串对象。这意味着,字符序列"abcde"
将存储在一个中心位置,并且每当"abcde"
再次使用相同的文字时,JVM 将不会创建新的 String 对象,而是使用缓存的String的引用。
s2
is guranteed to be a new String object, so in this case we have:
s2
保证是一个新的 String 对象,所以在这种情况下我们有:
s1 == s2 // is false
s1 == s3 // is true
s1.equals(s2) // is true
回答by aioobe
Some disassembly is always interesting...
一些拆解总是很有趣...
$ cat Test.java
public class Test {
public static void main(String... args) {
String abc = "abc";
String def = new String("def");
}
}
$ javap -c -v Test
Compiled from "Test.java"
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #7.#16; // java/lang/Object."<init>":()V
const #2 = String #17; // abc
const #3 = class #18; // java/lang/String
const #4 = String #19; // def
const #5 = Method #3.#20; // java/lang/String."<init>":(Ljava/lang/String;)V
const #6 = class #21; // Test
const #7 = class #22; // java/lang/Object
const #8 = Asciz <init>;
...
{
public Test(); ...
public static void main(java.lang.String[]);
Code:
Stack=3, Locals=3, Args_size=1
0: ldc #2; // Load string constant "abc"
2: astore_1 // Store top of stack onto local variable 1
3: new #3; // class java/lang/String
6: dup // duplicate top of stack
7: ldc #4; // Load string constant "def"
9: invokespecial #5; // Invoke constructor
12: astore_2 // Store top of stack onto local variable 2
13: return
}
回答by foret
String s = new String("FFFF")
creates 2 objects: "FFFF"
string and String
object, which point to "FFFF"
string, so it is like pointer to pointer (reference to reference, I am not keen with terminology).
String s = new String("FFFF")
创建 2 个对象:"FFFF"
字符串和String
对象,它们指向"FFFF"
字符串,所以它就像指向指针的指针(对引用的引用,我不热衷于术语)。
It is said you should never use new String("FFFF")
据说你永远不应该使用 new String("FFFF")
回答by Jon
The long answer is available here, so I'll give you the short one.
长答案可以在这里找到,所以我会给你一个简短的答案。
When you do this:
当你这样做时:
String str = "abc";
You are calling the intern()
method on String. This method references an internal poolof String
objects. If the String you called intern()
on already resides in the pool, then a reference to that String
is assigned to str
. If not, then the new String
is placed in the pool, and a reference to it is then assigned to str
.
您正在调用Stringintern()
上的方法。此方法引用了一个内部池的对象。如果您调用的 String已驻留在池中,则对该字符串的引用将分配给. 如果不是,则将 new放入池中,然后将对其的引用分配给。String
intern()
String
str
String
str
Given the following code:
鉴于以下代码:
String str = "abc";
String str2 = "abc";
boolean identity = str == str2;
When you check for object identity by doing ==
(you are literally asking: do these two references point to the same object?), you get true
.
当您通过执行检查对象标识时==
(您实际上是在问:这两个引用是否指向同一个对象?),您会得到true
.
However, you don't needto intern()
Strings
. You can force the creation on a new Object
on the Heap by doing this:
但是,你没有需要到intern()
Strings
。您可以Object
通过执行以下操作强制在堆上创建一个新的:
String str = new String("abc");
String str2 = new String("abc");
boolean identity = str == str2;
In this instance, str
and str2
are references to different Objects
, neither of which have been interned, so that when you test for Object
identity using ==
, you will get false
.
在这种情况下,str
和str2
是对不同 的引用Objects
,两者都没有被实习过,因此当您Object
使用测试身份时==
,您将获得false
.
In terms of good coding practice: do notuse ==
to check for String equality, use .equals()
instead.
在良好的编码习惯方面:千万不能使用==
检查字符串是否相等,用.equals()
代替。
回答by Awin
As Strings are immutable, when you do:
由于字符串是不可变的,当你这样做时:
String a = "xyz"
while creating the string, the JVM searches in the pool of strings if there already exists a string value "xyz"
, if so 'a'
will simply be a reference of that string and no new String object is created.
在创建字符串时,JVM 会在字符串池中搜索是否已经存在字符串 value "xyz"
,如果存在,'a'
则将只是该字符串的引用,并且不会创建新的 String 对象。
But if you say:
但是如果你说:
String a = new String("xyz")
you force JVM to create a new String
reference, even if "xyz"
is in its pool.
你强制 JVM 创建一个新的String
引用,即使"xyz"
它在它的池中。
For more information read this.
有关更多信息,请阅读此内容。