Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
连接两个字符串s1和s2时,生成的输出字符串s3将在java的堆或常量池中创建?_Java_String - Fatal编程技术网

连接两个字符串s1和s2时,生成的输出字符串s3将在java的堆或常量池中创建?

连接两个字符串s1和s2时,生成的输出字符串s3将在java的堆或常量池中创建?,java,string,Java,String,为什么S5没有引用常量池中的对象? 由于S3和S4在池中,这就是为什么在S3==S4 但是如果S5==S3&S5==S4结果为false,则表示S5不在池中。比较java中的字符串用法等于 在java对象中==比较内存地址 串S5=S1+S2 S1+S2返回新字符串对象 有些对象有不同的记忆地址 你可以用相等的数字来比较 系统输出打印Ln(S5等于(S4)) 如果有许多字符串对象,请使用StringBuilder 它们快速启动并使用最小内存串接的字符串文本被输入到字符串池中。但是,由变量串联产生

为什么
S5
没有引用常量池中的对象? 由于
S3
S4
在池中,这就是为什么在
S3==S4

但是如果
S5==S3
&
S5==S4
结果为false,则表示S5不在池中。

比较java中的字符串用法等于

在java对象中==比较内存地址

串S5=S1+S2

S1+S2返回新字符串对象

有些对象有不同的记忆地址 你可以用相等的数字来比较

系统输出打印Ln(S5等于(S4))

如果有许多字符串对象,请使用StringBuilder
它们快速启动并使用最小内存

串接的字符串文本被输入到字符串池中。但是,由变量串联产生的字符串不是。这就是为什么S3等于S4而不是S5。它们指的不是同一个对象。然而,(尽管我还没有测试出来)S5.equals(S4)应该返回true

String S1="He";
String S2="llow";
String S3="Hellow";
String S4="He"+"llow";
String S5=S1+S2;
System.out.println(S3==S4); // prints true
System.out.println(S5==S3); // prints false
System.out.println(S5==S4); // prints false
因为
S4=“He”+“llow”由编译器优化,并导致与“Hellow”相同的字符串,该字符串与
S3
共享,因此S4和S3具有相同的引用

System.out.println(S3==S4);//true
因为
S5
和S3是两个具有不同引用的不同对象

System.out.println(S5==S3);//false
和以前一样


比较对象时,通常希望比较内容(使用
equals()
),而不是地址/引用(使用
=
)。

通常,编译器使用常量字符串,甚至是通过串联创建的字符串。这就是为什么
S3
S4
是同一个对象

S5
但是会在运行时进行计算,这就是为什么它会创建一个新对象,不同(但等于)
S4
。如果您自己将其放入字符串池,您将再次得到与
S4
相同的对象,因此
S5.intern()==S4
将为真

请注意,不能保证
S5
S4
不同。更优化的编译器可以在编译时将其放入字符串池。

来自JLS

由常量表达式(§15.28)计算的字符串在 编译时,然后将其视为文本

在运行时通过连接计算的字符串是新创建的,并且 因此不同

对于字符串S4,您正在执行编译时连接

String S4=“He”+“llow”

因此,它引用与S3相同的对象

然而,
S1+S2
在运行时是一个串联,因此,它指的是比S3单独的字符串对象,尽管
S1+S2
S3
在意义上是等价的。 i、 e
(S1+S2).equals(S3)
将返回true


您可以使用
intern
方法将字符串放入池中字符串
s1
s4
都是编译时常量

编译器在编译时计算
“He”+“llow”
,并查询字符串池以确定结果是否已经存在,如果不存在,则将其放在那里

但是
s1+s2
的计算不是在编译时完成的,因此它的结果不是内部的。为什么?因为在理论上,另一个线程可以更改
s1
s2
的值,所以当我们在代码中得到这条指令时,它可能会将
s2
设置为
“foo”
,因此结果变成
“Hefoo”

作为作者,您可能知道没有线程会这样做,而且这些都是局部变量,但编译器不知道

如果将定义更改为:

System.out.println(S5==S4);//false

那么实际上,
s5==s3
的结果将是
true
!为什么?因为
final
关键字让编译器知道这些字符串不会被替换,它们是这些变量的最终值。因此它可以在编译时计算它,并获取池中已经存在的结果。

因为在
字符串S4=“He”+“llow”
对象在池中创建,这是编译时常量,与
S3=“Hellow”相同
两者都是池中的同一对象,但在运行时在堆中创建了
S5

您可能需要这样做,因为S3和S4也从常量池引用同一对象。正如您所说的,S5将从池引用意味着S5也将引用同一对象,那么为什么S5==S4&S5==S3给出false。@dubey theHarcortians S5不从池引用because S5在运行时创建为一个新字符串,基于变量S3和S4,这两个变量是文字值,因此在编译时输入到池中。谢谢。在运行时得到了一个点S5解析。我在我的问题中添加——如果在这段代码中添加相同的s6=s1+s2;那么S5==s6将输出什么?为什么?如果在这段代码中添加相同的s6=s1+s2;then s5==s6将输出什么?为什么?因为s1+s2将被计算两次,一次用于s5,一次用于s6,s5==s6将返回false。但是,正如所说的,不要依赖于此。一个聪明的编译器可以优化第二次计算。我在运行时得到了一个s5点解析。我在我的问题中添加了——如果在这段代码中我们添加相同的s6=s1+s2,那么会是什么s5==s6上的输出以及原因?可能是错误的,因为它们都是在运行时解析的。在运行时解析的字符串在堆上被创建为不同的对象。只有编译时的文本字符串和文本字符串串联可以放在字符串池中
    final String s1="He";
    final String s2="llow";
    final String s3="Hellow";
    final String s4="He"+"llow";
    final String s5=s1+s2;