==二元运算符和equals方法
根据数据类型的不同(值类型、引用类型、空类型),==运算符对于“值类型”和“空类型”,是比较他们的值;对于“引用类型”,比较的是他们在内存中的存放地址,即是否指向指向同一个对象。
Java中所有类都是继承于Object。Object类定义equals方法,这个方法的初始行为是比较对象的内存地址。实现如下:
public boolean equals(Object obj) {
return (this == obj);
}
但有些类库对这个方法进行了重写,如String,Integer,Date等,而不再是比较堆内存中的存放地址。
String
String对equals进行重写,比较值是否相等。实现如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
因为String重写的equals方法,所以下述代码返回为true。
String str1 = new String("123");
String str2 = new String("123");
// true
str1.equals(str2);
由于==运算符对于“引用类型”仅比较是否指向同一片内存,所以new的两个String实例不相等。示例代码如下:
String str1 = new String("123");
String str2 = new String("123");
// false
str1 == str2;
String包装器支持字面量赋值,当使用形如:stringInstance="xxx"方式创建字符串时,程序首先会在字符串缓冲池中寻找相同值的对象,如果池中无相同值的对象,则在池中添加一个值。所以以下代码值相等:
String str1 = "123";
// true
str1 == "123";
但也应注意,如果使用new的方式创建字符串示例,则使用==会认为两边不相等。示例代码如下:
String str1 = new String("123");
// false
str1 == "123";
Integer
为提高Integer等包装器的性能,Java引入缓存池。Integer有两种实例方式:new Integer(xxx) 与 Integer.valueOf(xxx) 。两者的区别在于:new Integer(xxx)方式每次都会新建一个对象;Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。在 Java 8 中,Integer 缓存池的大小默认为 -128~127。一旦超出这个范围,则不会缓存整数值。valueOf源码如下:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Short和Long
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
Float和Double
Float和Double未提供缓存池实现。使用时要特别注意。Float相关实现如下:
public static Float valueOf(float f) {
return new Float(f);
}
public Double(double value) {
this.value = value;
}
参考
https://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html Java中equals和的区别
https://www.cnblogs.com/tinyphp/p/3768214.html java:String使用equals和比较的区别
https://www.cnblogs.com/qiuhuashan/p/11053857.html [Java]缓存池
<cnblogs.com/Pjson/p/8777940.html> 深入剖析Java中的装箱和拆箱(缓存池技术)
原创不易,如果本文对您有帮助,欢迎关注我,谢谢 ~_~