字符串对象和字符串文字之间的区别
有什么区别
String str = new String("abc");
和
String str = "abc";
What is the difference between
String str = new String("abc");
and
String str = "abc";
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
当您使用字符串文字时,字符串可以interned,但是当你使用
new String("...")
你会得到一个新的字符串对象。在此示例中,两个字符串文字引用同一个对象:
这里,创建了 2 个不同的对象,并且它们具有不同的引用:
一般来说,您应该尽可能使用字符串文字表示法。它更容易阅读,并且让编译器有机会优化您的代码。
When you use a string literal the string can be interned, but when you use
new String("...")
you get a new string object.In this example both string literals refer the same object:
Here, 2 different objects are created and they have different references:
In general, you should use the string literal notation when possible. It is easier to read and it gives the compiler a chance to optimize your code.
字符串文字是一个Java语言概念。这是一个字符串文字:
String 对象是
java.lang.String
类的单个实例。全部都是有效的,但略有不同。
s1
将引用一个interned String 对象。这意味着,字符序列“abcde”
将存储在一个中心位置,并且每当再次使用相同的文字“abcde”
时,JVM将不会创建一个new String 对象,但使用缓存 String 的引用。s2
保证是一个新的 String 对象,因此在本例中我们有:A String literal is a Java language concept. This is a String literal:
A String object is an individual instance of the
java.lang.String
class.All are valid, but have a slight difference.
s1
will refer to an interned String 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 cached String.s2
is guranteed to be a new String object, so in this case we have:长答案可以在此处找到,所以我会给你一个简短的答案。
当您执行此操作时:
您正在调用 字符串。此方法引用
String
对象的内部池。如果您调用intern()
的字符串已驻留在池中,则对该String
的引用将分配给str
。如果没有,则将新的String
放入池中,然后将对其的引用分配给str
。给出以下代码:
当您通过执行
==
检查对象身份时(您实际上是在问:这两个引用是否指向同一个对象?),您会得到true
。但是,您不需要
intern()
Strings
。您可以通过执行以下操作强制在堆上创建新的Object
:在本例中,
str
和str2
是对不同的引用>Objects
,两者都没有被interned,因此当您使用==
测试Object
身份时,您将得到假
。就良好的编码实践而言:不要使用
==
来检查字符串是否相等,而是使用.equals()
。The long answer is available here, so I'll give you the short one.
When you do this:
You are calling the
intern()
method on String. This method references an internal pool ofString
objects. If the String you calledintern()
on already resides in the pool, then a reference to thatString
is assigned tostr
. If not, then the newString
is placed in the pool, and a reference to it is then assigned tostr
.Given the following code:
When you check for object identity by doing
==
(you are literally asking: do these two references point to the same object?), you gettrue
.However, you don't need to
intern()
Strings
. You can force the creation on a newObject
on the Heap by doing this:In this instance,
str
andstr2
are references to differentObjects
, neither of which have been interned, so that when you test forObject
identity using==
, you will getfalse
.In terms of good coding practice: do not use
==
to check for String equality, use.equals()
instead.由于字符串是不可变的,当您这样做时:
在创建字符串时,JVM 在字符串池中搜索是否已存在字符串值
"xyz"
,如果存在'a' 将只是该字符串的引用,并且不会创建新的 String 对象。
但如果您说:
您强制 JVM 创建一个新的
String
引用,即使"xyz"
在其池中。有关更多信息,请阅读此。
As Strings are immutable, when you do:
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.But if you say:
you force JVM to create a new
String
reference, even if"xyz"
is in its pool.For more information read this.
"abc"
是一个文字字符串。在 Java 中,这些文字字符串在内部进行池化,并且在代码中声明该字符串文字的任何地方都会使用
"abc"
的相同 String 实例。因此"abc" == "abc"
将始终为 true,因为它们都是相同的 String 实例。使用
字符串.intern()
方法中,您可以将任何您喜欢的字符串添加到内部池字符串中,这些字符串将保留在内存中,直到 java 退出。另一方面,使用
new String("abc")
将在内存中创建一个新的字符串对象,其逻辑上与"abc"
文字相同。"abc" == new String("abc")
始终为 false,因为尽管它们在逻辑上相等,但它们引用不同的实例。将 String 构造函数包装在字符串文字周围没有任何价值,它只是不必要地使用了比需要更多的内存。
"abc"
is a literal String.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.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.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.Wrapping a String constructor around a string literal is of no value, it just needlessly uses more memory than it needs to.
String是Java中与其他编程语言不同的类。因此,对于每个类,对象声明和初始化都是
or
这里,st1、st2 和 st3 是不同的对象。
即:
因为
st1
、st2
、st3
引用了 3 个不同的对象,并且==
检查相等性在内存位置,因此结果。但是:
这里
.equals()
方法检查内容,以及st1 = ""
、st2 = "hello"
和 <代码>st3 =“你好”。于是就有了这样的结果。在 String 声明的情况下
,调用
String
类的intern()
方法,并检查"hello"
是否在 intern 中如果没有,则添加到intern池中,如果intern池中存在“hello”,则st
将指向已存在的“hello”
的内存。因此,如果是:
这里:
因为
st3
和st4
指向相同的内存地址。还:
String is a class in Java different from other programming languages. So as for every class the object declaration and initialization is
or
Here,
st1
,st2
andst3
are different objects.That is:
Because
st1
,st2
,st3
are referencing 3 different objects, and==
checks for the equality in memory location, hence the result.But:
Here
.equals()
method checks for the content, and the content ofst1 = ""
,st2 = "hello"
andst3 = "hello"
. Hence the result.And in the case of the String declaration
Here,
intern()
method ofString
class is called, and checks if"hello"
is in intern pool, and if not, it is added to intern pool, and if "hello" exist in intern pool, thenst
will point to the memory of the existing"hello"
.So in case of:
Here:
Because
st3
andst4
pointing to same memory address.Also:
在第一种情况下,创建了两个对象。
在第二种情况下,只有一个。
尽管这两种方式
str
都引用"abc"
。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"
.一些拆解总是很有趣......
Some disassembly is always interesting...
除了已经发布的答案之外,还可以参见这篇关于javaranch的优秀文章。
In addition to the answers already posted, also see this excellent article on javaranch.
根据 String 类文档< /a> 它们是等价的。
String(String original)
的文档还指出:除非需要原始的显式副本,否则无需使用此构造函数,因为字符串是不可变的。寻找其他响应,因为 Java 文档似乎具有误导性:(
According to String class documentation they are equivalent.
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.Look for other responses, because it seems that Java documentation is misleading :(
以下是一些比较:
当调用
intern()
时,引用会发生更改。The following are some comparisons:
When
intern()
is called the reference is changed.String 对象和字符串文字之间存在细微差别。
在这个简单的例子中,“abc”将进入池中,s将引用它。
在本例中,因为我们使用了
new
关键字,Java 将创建一个新的 String 对象在普通(非池)内存中,s 将引用它。此外,文字“abc”将
被放置在水池中。
There is a subtle differences between String object and string literal.
In this simple case, "abc" will go in the pool and s will refer to it.
In this case, because we used the
new
keyword, Java will create a new String objectin normal (non-pool) memory, and s will refer to it. In addition, the literal "abc" will
be placed in the pool.
String s = new String("FFFF")
创建 2 个对象:"FFFF"
字符串和String
对象,它们指向" FFFF”
字符串,所以它就像指针到指针(引用到引用,我不热衷于术语)。据说你永远不应该使用
new String("FFFF")
String s = new String("FFFF")
creates 2 objects:"FFFF"
string andString
object, which point to"FFFF"
string, so it is like pointer to pointer (reference to reference, I am not keen with terminology).It is said you should never use
new String("FFFF")