在 Java 中,==
和 equals
是两个完全不同的操作,==
并不等价于调用 equals
方法,并且 ==
的底层也不是调用的 equals()
。具体来说:
==
的本质
- 用于比较两个变量的引用是否相等(对象类型)
- 用于基本数据类型,比较的是值是否相等(int、long等)
PS:在本质上,==
还是比较的值是否相等,对于数值类型,变量中直接存储的是值;对于对象类型,变量中实际存储的是一个指针,也就是堆中所存储对象的实际地址。因此,在使用==
判断时,数值类型就是判断值是否相等,引用类型(对象类型)判断的是是否为同一个对象。
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a == b); // 输出 false,因为 a 和 b 是两个不同的对象引用。
int x = 1;
int y = 1;
System.out.println(x == y); // 输出 true,因为基本类型比较的是值。
equals()
的本质
equals
是Object
类的方法,用于比较两个对象是否相等。Object
类中的默认实现是比较对象的引用地址,类似于==
,但两者只是相似。- 许多类(如
String
、Integer
等)重写了equals
方法,用来比较对象的内容是否相同。
PS:对于Integer var = ?
在-128~127
之间的赋值,Integer
对象是在IntegerCache.cache
产生,回复用已存在的对象,在这个区间内的Integer
值可以直接使用==进行判断,但是在这个区间之外的所有数据,都会在堆上产生,并不会复用已有的对象,这是一个大坑,推荐使用equals
进行判断。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // 输出 false,因为 s1 和 s2 是两个不同的对象。
System.out.println(s1.equals(s2)); // 输出 true,因为 String 重写了 equals 方法,比较的是字符串的值。
Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 == i2); // 输出 true,因为 i1 和 i2 属于-128~127,是复用的IntegerCache.cache中的同一个对象
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i3 == i4); // 输出 false,因为 i1 和 i2 不属于-128~127,对象在堆上产生,不服用同一对象
Integer i5 = new Integer(100);
Integer i6 = new Integer(100);
System.out.println(i5 == i6); // 输出 false,每一次 new 关键字产生的对象都是在堆中新生成的
总结:
==
用于比较引用是否相等(基本类型时比较值)。equals
是一个方法,默认行为和==
类似,但可以被重写用于比较对象的内容。==
的本质并不是调用equals
方法,它直接比较内存地址(引用)或基本数据类型的值。