在 Java 中,"==" 和 "equals" 有着不同的作用:
- "==" 运算符:
- 在基本数据类型(如 int、char 等)中,"==" 用于比较它们的值是否相等。
- 在引用类型中,"==" 比较的是对象引用(即内存地址)是否相同,即是否指向同一块内存。
- "equals" 方法:
- "equals" 是一个方法,用于比较对象的内容是否相等,它是 Object 类的方法,可以被子类覆盖重写。
- 默认情况下,Object 类中的 "equals" 方法是使用 "==" 比较两个对象的引用,因此如果没有在类中重写 "equals" 方法,那么使用 "equals" 和 "==" 会有相同的行为。
在源码中,"==" 实际上是在比较对象的引用,即比较两个对象的内存地址是否相同。这在 Java 虚拟机中通过比较对象的引用地址来实现。这是因为 "==" 操作符比较的是两个对象的引用,如果两个对象的引用指向的是同一个内存地址,则返回 true。
对于 "equals" 方法,它是一个可以被覆盖重写的方法。在 Object 类中的默认实现是直接使用 "==" 操作符来比较两个对象的引用地址。但是,许多类(如 String、Integer 等)会覆盖 "equals" 方法以实现内容比较而非引用比较。因此,"equals" 方法的实现可以根据类的需求而有所不同。
"==" 比较对象的引用,而 "equals" 方法用于比较对象的内容,但前提是需要根据需要在类中重写 "equals" 方法。
当涉及到Java中的"=="和"equals"时,以下是五种情况的示例,它们展示了这两者之间的不同:
1. 字符串比较
String str1 = new String("hello"); String str2 = new String("hello"); boolean usingEquals = str1.equals(str2); // 结果为true,因为equals方法比较字符串的内容 boolean usingDoubleEquals = str1 == str2; // 结果为false,因为这里比较的是对象的引用地址
在这个例子中,尽管对象的内容相同,但由于它们是两个不同的对象,所以使用"=="比较时,将会返回false。
2. 自定义类的比较
class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } Point p1 = new Point(2, 3); Point p2 = new Point(2, 3); boolean usingEquals = p1.equals(p2); // 结果为false,因为Point类中没有重写equals方法,所以比较的是引用地址 boolean usingDoubleEquals = p1 == p2; // 结果为false,同样是比较的引用地址
在这个例子中,即使这两个Point对象的属性值是相同的,但由于没有重写equals方法,因此"=="和"equals"都会比较对象的引用地址,从而导致返回false。
3. 包装类的比较
Integer num1 = 10; Integer num2 = 10; boolean usingEquals = num1.equals(num2); // 结果为true,因为Integer类重写了equals方法,比较的是内容 boolean usingDoubleEquals = num1 == num2; // 结果为true,因为Java缓存了-128到127之间的整数对象,所以它们的引用地址相同
这里的例子展示了使用"=="和"equals"比较两个Integer对象的差异。由于Java对整数对象进行了缓存,因此在-128到127之间的整数对象,使用"=="会返回true。
4. 数组比较
int[] arr1 = {1, 2, 3}; int[] arr2 = {1, 2, 3}; boolean usingEquals = Arrays.equals(arr1, arr2); // 结果为true,因为Arrays.equals方法比较的是数组的内容 boolean usingDoubleEquals = arr1 == arr2; // 结果为false,因为数组是不同的对象
在这个例子中,使用"=="比较两个数组将会返回false,因为数组是不同的对象。而使用Arrays.equals方法则会比较数组的内容,如果内容相同则返回true。
5. 枚举类型的比较
enum Weekday { MONDAY, TUESDAY, WEDNESDAY } Weekday day1 = Weekday.MONDAY; Weekday day2 = Weekday.MONDAY; boolean usingEquals = day1.equals(day2); // 结果为true,因为枚举类型已经重写了equals方法 boolean usingDoubleEquals = day1 == day2; // 结果为true,因为枚举类型的对象是唯一的
在这个例子中,枚举类型的对象是唯一的,因此无论使用"=="还是"equals"都会返回true。
总结
在Java中,“==”比较的是对象的引用地址,而“equals”方法用于比较对象的内容。重写“equals”方法允许自定义类根据需要执行内容比较。如果不重写,那么两者没有区别,因为equals底层还是用的==。对于基本数据类型,“==”比较它们的值是否相等。同时,“==”在比较包装类对象时,会受到Java整数缓存的影响。