我是Java的新手,我很难理解String比较。任何人都可以解释以下情况之间的差异吗?
情景1:
String a = "abc";
String b = "abc";
当我运行if(a == b)
时,它返回true。
情景2:
String a = new String("abc");
String b = new String("abc");
并运行if(a == b)
然后返回false。
有什么区别?
答案 0 :(得分:4)
==
运算符比较内存中两个对象的引用。如果它们指向相同的位置,则返回true。String
中的对象是Immutable,因此当您在scenario1中创建字符串时,它不会创建新的字符串。它只是将第二个字符串指向第一个字符串的内存位置。
但是,.equals()
方法会比较String的内容。当字符串具有相同的值时,此方法返回true。
因此,一般情况下,建议使用equals()
方法而不是==
。
答案 1 :(得分:4)
这是因为 Java String常量内存池。相同值的文字存储一次。
String a = "abc";
String b = "abc";
// Now there is 1 string ("abc") and 2 references pointing to it.
String a = new String("abc");
String b = new String("abc");
// Now you have 2 string instances and 2 references.
答案 2 :(得分:1)
由于编译器优化,场景1返回true。
通常,您应该使用equals()
代替==
来比较字符串。
答案 3 :(得分:1)
在Java中,您需要像if(str.equals(str2))
一样使用它来比较字符串的实际值而不是引用。
答案 4 :(得分:1)
<强>情况1:强>
String a = "abc";
String b = "abc";
if(a == b)
在这种情况下,abc
缓存在String常量池中,因此不会创建新字符串String b = "abc";
b
只是引用由 a 它返回true,因为a
和b
都指向内存中的同一个对象。
<强>情况2:强>
String a = new String("abc");
String b = new String("abc");
and run if(a == b) then it returns false.
这里创建了两个字符串,==
运算符只检查两个引用是否指向同一个引用,在这种情况下它不会返回false
答案 5 :(得分:1)
原因是字符串文字"abc"
将变成一个全局String实例,用于它的所有发生,它将是相同的String实例因此你可以确定{{ 1}}。编译器可以这样做,因为String实例是不可变的。但是,如果您显式分配String,它们将是两个不同的实例,它们也将与编译器隐式创建的String实例不同,即"abc" == "abc"
和new String("abc") != new String("abc")
。
了解编译器正在做什么的另一个好例子是查看此代码:
"abc" != new String("abc")
您会看到文字的行为类似于String类型的实例。您可以利用它来最小化编程错误,例如
"abc".contains("a");
而这段代码导致NPE:
// this is OK and the condition will evaluate to false
String myStringValue = null;
if ("abc".equals(myStringValue)) { // false
答案 6 :(得分:1)
创建字符串的两种方法是 1)String s =“hello”;字符串文字数= 1,即“hello” - 堆上的String对象数= 0
2)String s = new String(“hello”); - 字符串文字数= 1和字符串对象数= 1
Java维护一个字符串池“LITERALS”,对象将保留在堆上。
字符串池的优点:1)减少内存使用*(PermGenSpace问题)2)更快的比较,即==比较3)更快的查找 缺点:1)维护池的开销
如何池对象?在字符串上使用Intern()将其添加到池中。实习的缺点:1)你可能忘记实习一些字符串并通过==比较它们,从而导致意想不到的结果。