【equals()与 == 的区别】

目录

    • 1、超类Object的equals()底层原理:
    • 2、equals()与 == 的区别:
    • 3、equals()的重写规则:
    • 4、有关equals()与 == 号的小例子:
    • 5、重写equals()中 getClass 与 instaceof 的区别:

1、超类Object的equals()底层原理:

在Object超类中已经提供了equals()方法,源码如下:

public boolean equals(Object obj) {   return (this == obj);     }

所有的对象都拥有标识(内存地址)和状态(数据),同时“”比较的是两个对象的内存地址,在Object的equals()底层调用的是号,所以说Object的equals()是比较两个对象的内存地址是否相等,如果为true,则表示的引用的是同一个对象。

2、equals()与 == 的区别:

1、==是运算符;equal是方法。

2、==比较的是内存地址;equal比较的是内容。

3、==变量是否相同;equal值是否相等

3、equals()的重写规则:

自反性。对于任何非null的引用值x,x.equals(x)应返回true。

对称性。对于任何非null的引用值x与y,当且仅当:y.equals(x)返回true时,x.equals(y)才返回true。

传递性。对于任何非null的引用值x、y与z,如果y.equals(x)返回true,y.equals(z)返回true,那么x.equals(z)也应返回true。

一致性。对于任何非null的引用值x与y,假设对象上equals比较中的信息没有被修改,则多次调用x.equals(y)始终返回true或者始终返回false。

对于任何非空引用值x,x.equal(null)应返回false。

4、有关equals()与 == 号的小例子:

public class Test {
	public static void main(String[] args) {	
		String str1 = new String("abc");
		String str2 = new String("abc");
		System.out.println(str1 == str2);//false
		System.out.println(str1.equals(str2));//true
		
		String str3 = "123";
		String str4 = "123";
		System.out.println(str3 == str4);//true
		System.out.println(str3.equals(str4));//true	
	}
}

根据上面的demo输出结果可以看到,前面的输出结果是false、true,后面的输出结果是true、true。为什么两次==的输出结果不一样呢?这其实涉及到了内存中的常量池,常量池属于方法区的一部分,当运行到创建str3对象时,如果常量池中没有“123”,则在常量池中创建一个"123"对象,运行到str4对象时,由于“123”已经存在常量池,就直接使用,所以str3和str4对象其实是同一个对象,他们的地址引用相同。

而对于str1和str2,它们其实创建了两次对象,一次在常量池创建了对象“abc”,所以str1和str2的地址值是不相等的。

5、重写equals()中 getClass 与 instaceof 的区别:

在重写equals() 方法时,一般都是推荐使用 getClass 来进行类型判断,不是使用 instanceof(除非所有的子类有统一的语义才使用instanceof)。我们都知道 instanceof 的作用是判断其左边对象是否为其右边类的实例,返回 boolean 类型的数据,可以用来判断继承中的子类的实例是否为父类的实现。

下来我们来看一个例子:父类Person

public class Person {
        protected String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Person(String name){
            this.name = name;
        }
        public boolean equals(Object object){
            if(object instanceof Person){
                Person p = (Person) object;
                if(p.getName() == null || name == null){
                    return false;
                }
                else{
                    return name.equalsIgnoreCase(p.getName ());
                }
            }
            return false;
       }
    }

子类 Employee:

public class Employee extends Person{
        private int id;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public Employee(String name,int id){
            super(name);
            this.id = id;
        }
        /**
         * 重写equals()方法
         */
        public boolean equals(Object object){
            if(object instanceof Employee){
                Employee e = (Employee) object;
                return super.equals(object) && e.getId() == id;
            }
            return false;
        }
    }

上面父类 Person 和子类 Employee 都重写了 equals(),不过 Employee 比父类多了一个id属性,而且这里我们并没有统一语义。测试代码如下:

public class Test {
        public static void main(String[] args) {
            Employee e1 = new Employee("employee", 23);
            Employee e2 = new Employee("employee", 24);
            Person p1 = new Person("employee");
            System.out.println(p1.equals(e1));//true
            System.out.println(p1.equals(e2));//true
            System.out.println(e1.equals(e2));//false
        }
    }

你可能感兴趣的:(java,1024程序员节)