在 Java 中,"==" 和 "equals" 有着不同的作用:

  1. "==" 运算符:
  • 在基本数据类型(如 int、char 等)中,"==" 用于比较它们的值是否相等。
  • 在引用类型中,"==" 比较的是对象引用(即内存地址)是否相同,即是否指向同一块内存。
  1. "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整数缓存的影响。