Java 字符串初始化差异

Java 字符串初始化差异,java,memory-management,Java,Memory Management,首先,如果这是一个非常基本的问题,我很抱歉,我只是想知道以下字符串定义之间的区别 String x= "hello"; String y = new String("hello"); 我知道在java中字符串是一个类,它既不是原语也不是包装器(如果这是一个误解,请纠正我)。考虑A类,到目前为止,我看到了任何类的以下声明。我认为ac有效且A=新A()也是有效的。我对A=“xyz”感到困惑这就是我们在上面第一种定义类型中声明字符串的方式。我确信以上两个定义是完全不同的,比如如果我说x==y它返回f

首先,如果这是一个非常基本的问题,我很抱歉,我只是想知道以下字符串定义之间的区别

String x= "hello";
String y = new String("hello");
我知道在java中字符串是一个类,它既不是原语也不是包装器(如果这是一个误解,请纠正我)。考虑A类,到目前为止,我看到了任何类的以下声明。我认为
ac有效且
A=新A()也是有效的。我对
A=“xyz”感到困惑这就是我们在上面第一种定义类型中声明字符串的方式。我确信以上两个定义是完全不同的,比如如果我说
x==y
它返回false。我知道y是对String对象的引用。有意思的是,我发现x和y都可以访问String类的所有方法


那么一个比另一个有什么好处呢?我能知道每个答案的适用性吗。

你得到的前两个答案是不正确的。这两种说法之间存在差异。但首先是
TL;DR
version:使用
String x=“hello”在99.99999%的情况下

完整答案是:

这两者之间的主要区别在于,在第一种情况下,字符串是隐式的;在第二种情况下,情况并非如此。这是一个非常真实的差异,尽管它只在特定情况下发挥作用。因此,在第一种情况下,如果您有任何其他字符串具有相同的字符序列(
“hello”
),您的
x
将引用在所有这些位置使用的一个共享对象(这很有用,因为
String
实例是不可变的)。在第二种情况下,您明确表示(出于任何原因)需要一个
字符串
实例,该实例包含与任何其他字符串分开的字符序列。这样做的理由非常非常少

关于
x==y
,在Java中,使用
equals
而不是
=
来比较字符串是否相等。与对象引用一起使用时,
=
运算符比较引用(例如,两个变量是否指向同一对象),而不是对象内容


因此:除非你有很好的理由去做第二种形式,否则你更喜欢第一种形式而不是第二种形式。

摘自Joshua Bloch的《有效的Java》第二版:

语句每次执行时都会创建一个新的字符串实例, 这些物体的创造都不是必需的。这一论据符合事实 字符串构造函数(“stringette”)本身就是一个字符串实例, 功能上与由创建的所有对象相同 构造器。如果此用法发生在循环或频繁调用的 方法,则可以不必要地创建数百万个字符串实例。这个 改进的版本如下所示:

String s = "stringette";
所以
a==b
但是

a=c

非常简单,
x
的值是一个字符串。一个普通的
java.lang.String

您已经习惯了基本类型有文字的想法(例如,
7
,或
3.14159
,或
true
,或
'q'
),但您可能没有意识到的是,某些对象类型也有文字形式。我能想到的只有
java.lang.String
,在那里你可以写
“hello”
,还有
java.lang.Class
,在那里你可以写
SomeClass.Class

我知道y是对String对象的引用。那里的x是什么[…]

x
y
都是对
String
对象的引用。
x
是对ed字符串的引用(正如T.J.Crowder在他的回答中所写的那样),
y
是对具有相同内容的第二个
string
对象的引用。这意味着:

x == y       --> false
x.equals(y)  --> true
y.equals(x)  --> true
那么,一个比另一个有什么好处呢?我能知道每一个的适用性吗


始终使用第一个直接版本。我所遇到并发现的唯一有效异常是测试代码,它明确地希望确保要测试的代码不使用
=
进行字符串比较,而是使用正确的
x.equals(y)
方法。

还有一种初始化字符串的方法是

String str =("abc");

一开始,这似乎会给出一个错误(因为括号),但事实并非如此。令人惊讶的是。

为了学究气,文字产生的是飞锤而不是单重。Singleton意味着类只有一个实例,而flyweight对于每个不同的值(如枚举)都有一个实例Flyweight'现在不是一个很常见的术语,但它仍然很有用。谢谢你的评论,我知道Singlotis不准确,这就是为什么我用引号将它括起来。请注意,你应该将字符串与.equals()进行比较,而不是==原因
x==y
返回
False
是因为
=
比较了引用(或地址),而不是它们的内容-x和y的引用是不同的。与QPayStax状态一样,字符串必须与
.equals()
进行比较以检查它们的内容。
x == y       --> false
x.equals(y)  --> true
y.equals(x)  --> true
String str =("abc");