Java 中 == 和 equals() 的区别

Java 手册

equals

public boolean equals(Object obj)
指示其他某个对象是否与此对象“相等”。

equals 方法在非空对象引用上实现相等关系:

  • 自反性:对于任何非空引用值 xx.equals(x) 都应返回 true
  • 对称性:对于任何非空引用值 xy,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true
  • 传递性:对于任何非空引用值 xyz,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true
  • 一致性:对于任何非空引用值 xy,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
  • 对于任何非空引用值 xx.equals(null) 都应返回 false

Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 xy,当且仅当 xy 引用同一个对象时,此方法才返回 truex == y 具有值 true)。

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false
另请参见:
hashCode(), Hashtable

二者简单比较

== 比较的是地址,是栈里面的内容,地址信息都是存放在栈内存里面的。

equals 比较的是值,对象的值都是存放在堆内存里面的。

简单实例:

Integer a1 = new Integer(456);   //实例化一个对象
Integer a2 = new Integer(456);   //实例化一个对象
System.out.println(a1.equals(a2));   //这里比较的是值,都是456,结果是true
System.out.println(a1==a2);          //这里比较的是地址,因为是2个对象,所以地址不同,是false

注:Integer是属于包装类里面的引用类型。

equals 方法重写

系统会给定一个 equals()方法,

但是,一般equals()方法都是自己重写的,所以要明白equals()方法里面的详细架构。

 @Override
     public boolean equals(Object obj) {
    
         // 判断地址是否一致,如果地址相同,那么对象的值一定相同
         if (this == obj)
             return true;
        
         // 判断参数是否为空,如果传进来的参数是空,那肯定不相等
         if (obj == null)
             return false;
        
         // 判断类型是否一致,如果类型不一致,那么对象里面的值根本没有可比性
         if (this.getClass() != obj.getClass())
             return false;
        
         // 判断属性是否一致
         User user = (User) obj;
        
         if (this.username == null) {
             if (user.username != null)
               return false;
         } else if (!this.username.equals(user.username))
             return false;
        
         if (this.password == null) {
             if (user.password != null)
             return false;
         } else if (!this.password.equals(user.password))
             return false;
        
         return true;
    
     }

注:

username 和 password 两个参数都是自己定义的,其它代码都是自动生成的。

User user = (User) obj;是根据代码中 username 和 password 两个成员变量所在的类生成的,

在这里创建一个对象是为了判断这两个成员变量的栈地址是否相同。

完整的实例代码:

package cn.tedu.object;

public class ObjectExer {

}

class User {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    // hashCode的重写:
    // 如果两个对象equals为true,那么哈希码一致
    // 不同对象的哈希码要不同并且要做到散列分布
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((password == null) ? 0 : password.hashCode());
        result = prime * result + ((username == null) ? 0 : username.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj)
            return true;

        if (obj == null)
            return false;

        if (getClass() != obj.getClass())
            return false;

        User other = (User) obj;

        if (password == null) {
            if (other.password != null)
                return false;
        } else if (!password.equals(other.password))
            return false;

        if (username == null) {
            if (other.username != null)
                return false;
        } else if (!username.equals(other.username))
            return false;

        return true;
    }
}

猜你喜欢

转载自www.cnblogs.com/chuijingjing/p/9503160.html