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