详细探讨了equals和==在比较int和Integer以及对象之间相互比较的结果,及其原因
建议自己敲代码,复现每一种情况,加深了解,彻底搞懂其原理
Talk is cheap,Show you the code!
import java.util.ArrayList;
class Student{
private int id;
private String name;
public Student(){};
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
int i = 100;
Integer a = 100;
Integer b = 100;
Integer a2 = 200;
Integer b2 = 200;
Integer c = new Integer(100);
Integer d = new Integer(100);
Student student1 = new Student(1,"zs");
Student student2 = new Student(2,"ls");
Student student3 = student1;
System.out.println("**************************************int和Integer比较**********************************************\n");
System.out.print("int i=100 和 Integer a=100 通过 == 比较: ");
System.out.println(i == a);
System.out.println("相等,因为包装类Integer 和 基本数据类型int 比较时,java会自动拆箱为int ,然后比较值是否相等,实际上就变为两个int变量值的比较\n");
System.out.print("Integer a=100 和 Intager b=100 通过 == 比较:");
System.out.println(a == b);
System.out.println("因为Integer a = 100 系统将int类型的100自动装箱为Integer对象,然后比较内存地址");
System.out.println("但是,当Int值在-128—127之间时,两个Integer变量引用的是IntegerCache中的同一个对象,所以比较内存地址相同\n");
System.out.print("Integer a=100 和Integer a2=200 通过 == 比较:");
System.out.println(a == a2);
System.out.print("Integer a=100 和Integer a2=200 通过 equals() 比较:");
System.out.println(a.equals(a2));
System.out.println("因为Int值 a2=200 超过127,会通过new来创建一个新的对象,所以地址值和a不相同");
System.out.println("Integer缓存了-128~127之间的数,这是在类加载期间就完成的。以后需要的时候直接指向它就可以了,省去了构造对象的开支,提高了效率\n");
System.out.print("new Integer(100) 和 new Integer(100) 通过 == 比较:");
System.out.println(c == d);
System.out.print("new Integer(100) 和 new Integer(100) 通过 equals() 比较:");
System.out.println(c.equals(d));
System.out.println("因为Integer的equals() 方法会将Integer拆箱为int比较值是否相等,所以为true;而==直接比较地址值,所以为false\n");
System.out.println("**************************************Object之间比较*************************************************");
System.out.println("student1的内存地址值为:" + student1.hashCode());
System.out.println("student2的内存地址值为:" + student2.hashCode());
System.out.println("student3的内存地址值为:" + student3.hashCode());
System.out.println("\n");
System.out.print("student1 == student2:");
System.out.println(student1 == student2);
System.out.print("student1.equals(student2):");
System.out.println(student1.equals(student2));
System.out.println("对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价\n");
System.out.print("student1 == student3:");
System.out.println(student1 == student3);
System.out.print("student1.equals(student3):");
System.out.println(student1.equals(student3));
System.out.println("因为student3是指向student1的一个引用,内存地址相同,所以都为true\n");
}
}
执行结果
**************************************int和Integer比较**********************************************
int i=100 和 Integer a=100 通过 == 比较: true
相等,因为包装类Integer 和 基本数据类型int 比较时,java会自动拆箱为int ,然后比较值是否相等,实际上就变为两个int变量值的比较
Integer a=100 和 Intager b=100 通过 == 比较:true
因为Integer a = 100 系统将int类型的100自动装箱为Integer对象,然后比较内存地址
但是,当Int值在-128—127之间时,两个Integer变量引用的是IntegerCache中的同一个对象,所以比较内存地址相同
Integer a=100 和Integer a2=200 通过 == 比较:false
Integer a=100 和Integer a2=200 通过 equals() 比较:false
因为Int值 a2=200 超过127,会通过new来创建一个新的对象,所以地址值和a不相同
Integer缓存了-128~127之间的数,这是在类加载期间就完成的。以后需要的时候直接指向它就可以了,省去了构造对象的开支,提高了效率
new Integer(100) 和 new Integer(100) 通过 == 比较:false
new Integer(100) 和 new Integer(100) 通过 equals() 比较:true
因为Integer的equals() 方法会将Integer拆箱为int比较值是否相等,所以为true;而==直接比较地址值,所以为false
**************************************Object之间比较*************************************************
student1的内存地址值为:356573597
student2的内存地址值为:1735600054
student3的内存地址值为:356573597
student1 == student2:false
student1.equals(student2):false
对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价
student1 == student3:true
student1.equals(student3):true
因为student3是指向student1的一个引用,内存地址相同,所以都为true
补充
Intager的equals()方法源码:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
// 将Integer类型拆箱后,比较值是否相等
return value == ((Integer)obj).intValue();
}
return false;
}
Object的equals()方法源码:
public boolean equals(Object obj) {
// 比较引用的是否相同
return (this == obj);
}
Intager的hashCode()方法源码:
public int hashCode() {
// 返回int值
return Integer.hashCode(value);
}
Integer源码
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
PS:时间仓促没写总结,建议自己代码实现,比背概念有用得多,有错误欢迎留言指正!
版权声明:本文为qq_43792852原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。