今天看到有线程同步的代码直接使用了String对象作为锁对象,心想可能会出问题,因为String对象可能表面上内容一样,但是实际上却不是同一个对象地址。Java字符串比较 == 判断是地址是否相等,equals判断是内容是否相等。但是String类有个本地方法intern,可以让不同对象地址的字符串,使用==时返回true,来看下定义:
方法返回字符串对象的标准表示。重点在When段落。当字符串池中存在通过equals方法相等的字符串时,返回该字符串常量。如果不存在,则将字符串加入到常量池后再返回。由此可见,最终返回的都是字符串常量。所以当==比较两个都是常量池中的元素时,就会返回true。不过用intern返回的常量比较堆上字符串对象地址,仍然会是false,注意对等。下面简单举个例子:
package com.huayu.java91up;
/**
* Create by zxb on 2017/4/18
*/
public class Test {
public static void main(String[] args) {
String orgin = "Hello";
String orgin2 = "Hello";
String token0 = "Say-Hello";
String token1 = "Say-" + orgin;
String token2 = "Say-" + orgin2;
String token3 = orgin.substring(0);
String token4 = orgin.substring(0);
String token5 = orgin.substring(1);
String token6 = orgin.substring(1);
String token7 = new String("Hello");
String token8 = new String("Say-Hello");
System.out.println("orgin == orgin2 -> " + (orgin == orgin2));
System.out.println("token0 == token1 -> " + (token0 == token1));
System.out.println("token1 == token2 -> " + (token1 == token2));
System.out.println("token3 == token4 -> " + (token3 == token4));
System.out.println("token5 == token6 -> " + (token5 == token6));
System.out.println("token0.intern() == token1.intern() -> " + (token0.intern() == token1.intern()));
System.out.println("token1.equals(token2) -> " + (token1.equals(token2)));
System.out.println("orgin == token7 -> " + (orgin == token7));
System.out.println("token1 == token8 -> " + (token1 == token8));
System.out.println("token0 == token8.intern() -> " + (token0 == token8.intern()));
System.out.println("token1.intern() == token8.intern() -> " + (token1.intern() == token8.intern()));
}
}
执行结果如下: