在Java中,== 和 equals() 是两种不同的比较方式,用于比较对象或基本数据类型,但它们在比较时的行为是不同的。
== 操作符:
当用于比较基本数据类型(如 int, char, boolean 等)时,== 比较的是它们的值是否相等。
当用于比较对象引用时,== 比较的是两个引用是否指向内存中的同一个对象实例。换句话说,它检查的是对象的身份(identity),而不是对象的内容或状态。
equals() 方法:
equals() 是 Object 类中的一个方法,所有Java对象都继承了这个方法。它的默认实现实际上与 == 相同,即比较对象的引用。
但是,很多类(尤其是那些需要比较对象内容的类)会重写 equals() 方法,以便根据对象的属性或状态来定义“相等性”。例如,String 类、Integer 类和自定义的类可能会重写 equals() 方法。
当重写 equals() 方法时,必须满足一些基本规则,包括自反性、对称性、传递性、一致性和非空性(前面已提到)。
引用数据类型大致包括:类、 接口、 数组、 枚举、 注解、 字符串等
它和基本数据类型的最大区别就是:
基本数据类型是直接保存在栈中的
引用数据类型在栈中保存的是一个地址引用,这个地址指向的是其在堆内存中的实际位置。(栈中保存的是一个地址,而实际的内容是在堆中,通过地址去找它实际存放的位置)
String s1 = new String("hello");
String s2 = new String("hello");
// 使用 == 操作符比较,结果是 false,因为 s1 和 s2 指向不同的对象实例
System.out.println(s1 == s2); // 输出 false
// 使用 equals() 方法比较,结果是 true(假设 String 类已正确重写 equals()),
// 因为 s1 和 s2 的内容相同
System.out.println(s1.equals(s2)); // 输出 true
// 对于字符串字面量,Java 会使用字符串池来优化性能,
// 因此下面的比较将返回 true,因为两个引用指向同一个字符串对象
String s3 = "hello";
String s4 = "hello";
System.out.println(s3 == s4); // 输出 true