==和equals()的区别

==和equals()方法都可以判断是否相等,那么二者有何区别?

==用于基本数据类型之间的比较,当比较引用对象时,比较的是否引用到堆上的同一个对象。

equals()判断两个对象是否存在意义上相等。相等的意义要看对象的类型来判断,比如两个不同的String带有相同的字符,这样可以认为是相等的;但对Dog对象来说,age和name一样的,未必就是一样。

equals()方法是基于Object类的,而通过源码发现equals()方法底层依赖的是==号,也就是说在没有重写equals()方法的类中,调用equals()方法的效果和==是一样的,也是比较的是地址值。

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

创建一个Book类用于测试说明==和equals的区别

   /**
     * 创建一个Book类用于测试说明==和equals
     */
    class Book{
        public Book(){

        }
        public Book(int size,double price,String name){
            this.size = size;
            this.price = price;
            this.name = name;
        }
        private int size;
        private double price;
        private String name;
        public int getSize() {
            return size;
        }

        public void setSize(int size) {
            this.size = size;
        }

        public double getPrice() {
            return price;
        }

        public void setPrice(double price) {
            this.price = price;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

创建测试类进行测试

 @Test
    public void testEqual(){
        Book c = new Book(1,2.0,"Java");
        Book d = new Book(1,2.0,"Java");
        Book e = d;
     //size,price都属于基本数据类型,没有equals()方法,故比较时采用== System.out.println(c.getSize()
== d.getSize());//true System.out.println(c.getPrice() == d.getPrice());//true System.out.println(c.getName().equals(d.getName()));//true System.out.println(c == d);//false; System.out.println(c == e);//false System.out.println(e == d);//true System.out.println(e.equals(d));//true System.out.println(c.equals(d));//false }

再来看一个例子

String str1 = new String("aaa");
String str2 = new String("aaa");
System.out.println(str1.equals(str2));//true
System.out.println(str1 == str2);//false

这个例子equals()方法返回true,==返回false,初看之下或许会觉得和我们上面讲的有矛盾,其实不然,String类中重写了equals()方法,所以会返回true。看一下String类中的equals()方法源码

 
 
private final char value[];
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

还有最后一个例子

String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));//true
System.out.println(s1 == s2);//true

我们说了对于引用类型比较的是两个地址是否相等,那么为什么两个都是true?这涉及到常量池,当创建s1是,常量池中如果没有,那么就会创建一个"abc",当创建s2时,并不会重新创建而是直接使用该常量。

String str1 = new String("aaa"); 中创建了两次对象,首先在常量池中创建了"aaa",然后在堆内存中又开辟一块str1。所以str1和str2的地址不等,而s1和s2的地址是相等的。

猜你喜欢

转载自www.cnblogs.com/noob-mengling/p/9179123.html
今日推荐