if("String ".intern().trim()=="String"){
System.out.println("Equals");
}else{
System.out.println("Unequal");
}
上面的代码显示Unequal
.我不明白为什么?有人可以解释一下吗?
我不太确定你面对的是什么,但如果你想使用intern()
方法比较字符串的地址,这也将起作用:
if ("String ".trim().intern() == "String") {
System.out.println("Equals");
} else {
System.out.println("Unequal");
}
您只需交换trim()
和intern()
呼叫。
intern()
搜索堆上已有的字符串并解决此问题。使用==
比较字符串时,地址将相等。
为了获得更好的可视化:
Value Evaluates to Address Explanation
"String" "String" 1 Creates new "String"
"String " "String " 2 Creates new "String "
"String ".trim() "String" 3 trim() creates new "String"
"String ".trim().intern() "String" 1 intern() finds the already created "String"
"String ".intern() "String " 2 intern() finds the already created "String "
"String ".intern().trim() "String" 4 trim() creates new "String"
这也是因为trim()
正在产生new String()
。
要自己尝试:
public class StringCompare {
public static void main(String[] args) {
System.out.println(System.identityHashCode("String"));
System.out.println(System.identityHashCode("String "));
System.out.println(System.identityHashCode("String ".trim()));
System.out.println(System.identityHashCode("String ".trim().intern()));
System.out.println(System.identityHashCode("String ".intern()));
System.out.println(System.identityHashCode("String ".intern().trim()));
}
}
将输出如下内容:
1500673861 // 1
1777631459 // 2
859434349 // 3
1500673861 // 1
1777631459 // 2
538093921 // 4
你需要知道字符串文字默认放置在字符串池中,就像
String s = "Hello";//this will be in string pool
但默认情况下,运行时通过new String(...)
创建的字符串不会从此池中放置或检索。
String s2 = new String(s);// or even `new String("Hello")`
System.out.println(s == s2);// returns false, which means s2 holds different String
// object then from String pool
现在substring
返回new String(...)
对象,因此这意味着它们不是来自字符串池。
trim
内部使用substring
方法,如果
- 指定为子字符串的范围将不同于 0,直到长度将返回
new String
具有指定范围字符的对象 - 范围从 0 到字符串长度(理想情况下覆盖整个字符串)返回相同的字符串,
return this;
所以在你的代码中,你试图将"String "
放在字符串池中(你不必这样做,因为你正在使用已经放在池中的字符串文字"String "
),然后你在这个对象上使用trim
方法,所以由于有部分要修剪,它将创建并返回新的字符串, 与原始版本不同,绝对不是与字符串池不同,因此将其与"String"
文字与==
进行比较将返回false
。
"String".intern()
创建一个存储在permgen或元空间中的String的不同实例,而原始实例存储在常规堆上。因此,您的比较将永远是错误的。
始终使用equals()
方法比较字符串!!
尝试这样的事情:
if("String ".trim().equals("String")){
System.out.println("Equals");
}else{
System.out.println("Unequal");
}
有用的链接
- ==, .equals(), compareTo(), and compare()
- 比较字符串和字符串的一部分
- 我们什么时候应该使用字符串常量的字符串的实习方法(堆栈溢出示例)