什么使参考比较(==)在Java中的一些string工作?
我有以下几行代码来比较string。 str1不等于str2,这是可以理解的,因为它比较了对象引用。 但是为什么s1等于s2?
String s1 = "abc"; String s2 = "abc"; String str1 = new String("abc"); String str2 = new String("abc"); if (s1==s2) System.out.println("s1==s2"); else System.out.println("s1!=s2"); if (str1==str2) System.out.println("str1==str2"); else System.out.println("str1!=str2"); if (s1==str1) System.out.println("str1==s1"); else System.out.println("str1!=s1");
输出:
s1==s2 str1!=str2 str1!=s1
string常量池本质上将caching所有string文本,因此它们是下面相同的对象,这就是为什么您会看到为s1==s2
执行的输出。 这实质上是VM中的一个优化,以避免每次声明文字时创build一个新的string对象,这可能会非常快速地花费很多! 以你的str1==str2
为例,你明确地告诉VM创build新的string对象,因此它是错误的。
另外,对任何string调用intern()
方法都会将其添加到常量池中(并返回将其添加到池中的String)。但是,除非确定“重新处理那些肯定会被用作常量的string,否则你可能最终难以追踪内存泄漏。
s1和s2是string文字。 当您创build一个新的string文字时,编译器会首先检查string池中是否存在表示相同的文字。 如果有一个存在,编译器将返回该文字,否则编译器会创build一个新的文字。
当您创buildString s2
,编译器将返回来自池的strings1
,因为它之前已经创build。 这就是s1
和s2
相同的原因。 这种行为被称为实习 。
这种现象是由于stringinterning 。
基本上,所有string文字都被“caching”并重用。
这是由于string文字被实施。 在这个问题上, Java文件说:
所有文字string和string值的常量expression式都被禁用
这就解释了为什么s1
和s2
是相同的(这两个variables指向相同的string)
在Java中,相同的常量string将被重用。 因此, s1
和s2
指向相同的“abc”对象和s1==s2
。 但是,当你使用new String("abc")
,另一个对象将被创build。 这样s1 != str1
。
由于
string
在java中是不可变的,所有的string literals
都是为了重用而caching的。
当你使用new()运算符创buildString对象时,它总是在堆内存中创build一个新的对象。 另一方面,如果使用string文字语法(例如“Java”)创build对象,则可以从string池(在Perm gen空间中的一个string对象caching,现在在最近的Java版本中移动到堆空间)返回一个现有对象。 ,如果它已经存在。 否则,它将创build一个新的string对象并放入string池以供将来重新使用。
String s1 = new String("java"); String s2 = new String("java"); String s3 = "java"; String s4 = "java";
请参考这个链接