java面试经典基础题——“==“与equals的区别详解

在Java中,==equals() 方法用于比较对象,但它们的功能和用途有所不同。下面是区别详解:
(一)

  1. == 运算符

    • 用于比较两个变量是否引用同一个对象,即比较它们的内存地址是否相同。
    • 对于基本数据类型,== 比较的是它们的值。
    • 对于引用数据类型,== 比较的是它们的内存地址。
  2. equals() 方法

    • 用于比较两个对象的内容是否相同。
    • equals() 方法在 Object 类中定义,可以被覆盖以提供类特定的比较逻辑。
    • 默认情况下,Object 类的 equals() 方法实现是使用 == 运算符进行比较,但很多类(如 StringInteger 等)都重写了 equals() 方法以比较对象的内容。

下面通过几个示例来说明 ==equals() 的区别:

示例1:基本数据类型比较

public class Main {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;

        System.out.println(a == b); // 输出: true
    }
}

示例2:引用数据类型比较(使用 ==

public class Main {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");

        System.out.println(str1 == str2); // 输出: false,因为它们是不同的对象
    }
}

示例3:引用数据类型比较(使用 equals()

public class Main {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");

        System.out.println(str1.equals(str2)); // 输出: true,因为字符串内容相同
    }
}

示例4:自定义类的比较

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("John", 25);
        Person p2 = new Person("John", 25);
        Person p3 = p1;

        System.out.println(p1 == p2); // 输出: false,因为它们是不同的对象
        System.out.println(p1.equals(p2)); // 输出: true,因为内容相同
        System.out.println(p1 == p3); // 输出: true,因为p3引用的是p1
    }
}

小结

  • 使用 == 来比较基本数据类型的值或引用是否相同。
  • 使用 equals() 来比较对象的内容是否相同。
  • 对于自定义类,建议重写 equals() 方法,以便正确比较对象内容。

(二)
在上述示例中可以看到,并没有equals()方法用来比较基本数据类型的示例,这是因为在Java中,equals() 方法不能用于比较基本数据类型。它主要用于比较引用类型的对象内容。基本数据类型需要通过它们的包装类来进行 equals() 比较。

Java的基本数据类型包括:intcharbyteshortlongfloatdoubleboolean。这些类型没有 equals() 方法,因为它们不是对象。

然而,每个基本数据类型都有相应的包装类,这些包装类继承自 Object 类并且重写了 equals() 方法。包装类包括:IntegerCharacterByteShortLongFloatDoubleBoolean

下面是一些示例,展示了如何使用包装类的 equals() 方法来比较基本数据类型的值:

示例:使用 Integer 类比较 int

public class Main {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;

        Integer intA = a;
        Integer intB = b;

        System.out.println(intA.equals(intB)); // 输出: true
    }
}

示例:使用 Double 类比较 double

public class Main {
    public static void main(String[] args) {
        double x = 5.5;
        double y = 5.5;

        Double doubleX = x;
        Double doubleY = y;

        System.out.println(doubleX.equals(doubleY)); // 输出: true
    }
}

示例:使用 Boolean 类比较 boolean

public class Main {
    public static void main(String[] args) {
        boolean p = true;
        boolean q = true;

        Boolean boolP = p;
        Boolean boolQ = q;

        System.out.println(boolP.equals(boolQ)); // 输出: true
    }
}

小结

  • 基本数据类型不能直接使用 equals() 方法。
  • 需要将基本数据类型转换为相应的包装类对象,然后使用包装类的 equals() 方法来比较值。
  • 包装类提供了更丰富的方法和功能,可以方便地操作基本数据类型的值。

(三)
在Java中,equals() 方法用于比较引用数据类型时,比较的是对象的内容,而不是内存地址。具体的比较内容取决于对象所属类对 equals() 方法的实现。以下是一些常见情况及示例:

  1. 默认实现

    • 默认情况下,Object 类的 equals() 方法使用 == 运算符比较两个对象的内存地址(即引用是否相同)。
  2. 重写实现

    • 很多类重写了 equals() 方法,以便比较对象的内容。例如,String 类、包装类(如 IntegerDouble 等)、ArrayList 等都重写了 equals() 方法。

示例1:String 类的 equals() 方法

String 类重写了 equals() 方法,用于比较字符串的内容是否相同。

public class Main {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");

        System.out.println(str1.equals(str2)); // 输出: true,因为字符串内容相同
    }
}

示例2:包装类的 equals() 方法

Integer 类重写了 equals() 方法,用于比较整数值是否相同。

public class Main {
    public static void main(String[] args) {
        Integer num1 = new Integer(100);
        Integer num2 = new Integer(100);

        System.out.println(num1.equals(num2)); // 输出: true,因为整数值相同
    }
}

示例3:自定义类的 equals() 方法

为了比较自定义类的对象内容,需要重写 equals() 方法。

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("John", 25);
        Person p2 = new Person("John", 25);

        System.out.println(p1.equals(p2)); // 输出: true,因为两个Person对象的name和age相同
    }
}

重要的重写原则:

  1. 对称性:如果 a.equals(b) 返回 true,那么 b.equals(a) 也应该返回 true
  2. 传递性:如果 a.equals(b)b.equals(c) 都返回 true,那么 a.equals(c) 也应该返回 true
  3. 一致性:如果对象没有被修改,多次调用 equals() 方法应该返回相同的结果。
  4. 非空性:对于任何非空引用值 aa.equals(null) 应该返回 false

通过重写 equals() 方法,我们可以确保在比较自定义对象时,能够根据对象的实际内容进行比较,而不是简单地比较内存地址。

(四)
在Java中,equals() 方法的行为取决于类对它的实现。以下是更详细的解释:

  1. 默认情况下(没有重写 equals() 方法)

    • 所有类都直接或间接继承自 Object 类,而 Object 类的 equals() 方法默认使用 == 运算符比较对象的内存地址。
    • 如果一个类没有重写 equals() 方法,那么使用 equals() 比较该类的对象时,比较的就是内存地址,即是否引用同一个对象。
  2. 重写 equals() 方法的类

    • String 类、Integer 类以及许多其他常用的类都重写了 equals() 方法,以便比较对象的内容而不是内存地址。
    • 例如,String 类重写了 equals() 方法,以比较字符串的字符序列是否相同,而不是比较字符串对象的内存地址。

示例说明

1. 默认的 equals() 方法(比较内存地址)
class MyClass {
    int value;

    MyClass(int value) {
        this.value = value;
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj1 = new MyClass(10);
        MyClass obj2 = new MyClass(10);

        System.out.println(obj1.equals(obj2)); // 输出: false,因为MyClass没有重写equals方法,比较的是内存地址
    }
}
2. 重写 equals() 方法(比较对象内容)
class MyClass {
    int value;

    MyClass(int value) {
        this.value = value;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        MyClass myClass = (MyClass) obj;
        return value == myClass.value;
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj1 = new MyClass(10);
        MyClass obj2 = new MyClass(10);

        System.out.println(obj1.equals(obj2)); // 输出: true,因为重写了equals方法,比较的是对象的内容
    }
}

小结

  • 默认实现:如果一个类没有重写 equals() 方法,那么 equals() 方法与 == 运算符的行为相同,比较的是对象的内存地址。
  • 重写实现:如果一个类重写了 equals() 方法,那么 equals() 方法比较的是对象的内容,具体内容取决于类的实现方式。
  • 在使用 equals() 方法时,需要了解该类是否重写了 equals() 方法以及重写的具体逻辑,从而正确理解比较的含义。
  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值