• Java中的==和equals()的区别


    1. 对于基本类型(byte, short, int, long, char, float, double, boolean)

        ==运算符比较的是两个数的值,不能进行equals()比较,因为不是对象,equals()是Object类的方法

    2. 对于引用类型

       2.1 ==进行的是地址比较

            自定义一个Animal类

     1 public class Animal {
     2 
     3     publicString name;
     4 
     5     public Animal(){
     6     }
     7 
     8     Animal(String name) {
     9         this.name = name;
    10     }
    11 }

          创建Animal对象并进行==比较

    1 public class DemoEquals {
    2     public static void main(String[] args) {
    3         Animal cat1 = new Animal("傻猫");
    4         Animal cat2 = new Animal("傻猫2");
    5         System.out.println("cat1: " + cat1);
    6         System.out.println("cat2: " + cat2);
    7         System.out.println(cat1 == cat2);
    8     }
    9 }

      运行结果

        

            分析

            cat1 == cat2,比较的是地址值,地址值从运行结果来看是不一样的,所以cat1 == cat2是false;

            现在我们验证一下,

     1 public class DemoEquals {
     2     public static void main(String[] args) {
     3         Animal cat1 = new Animal("傻猫");
     4         Animal cat2 = new Animal("傻猫2");
     5         System.out.println("cat1: " + cat1);
     6         System.out.println("cat2: " + cat2);
     7         System.out.println("========");
     8         cat1 = cat2;   // 让cat1对象和cat2对象共享一块内存区
     9         System.out.println("cat1: " + cat1);
    10         System.out.println("cat2: " + cat2);
    11         System.out.println(cat1 == cat2);
    12     }
    13 }

            运行结果 

            

            分析

            可以看出,执行了cat1 = cat2之后,cat1和cat2的地址值是一样的,进行==比较的结果就是true了。所以说,在应用类型中,== 进行的是地址比较。

        2.2 equals()比较

            我们首先要知道,equals(Object obj)这个方法是Object这个类定义的一个方法。我们自定义的所有的类都是继承这个Object类的,所以也都有equals()这个方法。那我们先看看Object类中是如何定义这个方法的

           

            this表示的是当前使用equals方法的这个对象,obj是我们传的参数的对象。但是这儿分明是进行==比较啊,不应该是进行地址比较吗。为什么我们在String对象中用equals()可以进行值比较呢?因为String类中重写了该方法,equals()方法默认是进行地址比较,String类中重写了之后,进行的是值比较,那么我们看一下String源码中是如何重写该方法的。

           

            这段代码能看懂就好,看不懂也没关系,只要知道,String类中重写了equals()方法,所以才能进行值比较,否则默认都是进行地址比较。我们可以来个实例

            创建Animal类

     1 public class Animal {
     2 
     3     publicString name;
     4 
     5     public Animal(){
     6     }
     7 
     8     Animal(String name) {
     9         this.name = name;
    10     }
    11 }

             然后创建Animal对象进行equals比较

    public class DemoEquals {
        public static void main(String[] args) {
            Animal cat1 = new Animal("傻猫");
            Animal cat2 = new Animal("傻猫2");
            System.out.println("cat1: " + cat1);
            System.out.println("cat2: " + cat2);
            System.out.println(cat1.equals(cat2));
            System.out.println("========");
            cat1.name = cat2.name;   // 修改名字,使得两个对象的name一样
            System.out.println("cat1: " + cat1);
            System.out.println("cat2: " + cat2);
            System.out.println(cat1.equals(cat2));
        }
    }

            运行结果

            

           分析

            可以看到比较结果和之前的==比较式一样的,尽管他们名字一样,但是比较的结果还是false,因为我们Animal对象中并没有重写equals()方法,所以它就自动继承了Object中的equals()方法,比较的还是地址值

            现在我们在Animal类中重写equals()方法

     1 @Override
     2     public boolean equals(Object obj){
     3         // 重写Object类的equals方法
     4         if (obj == this) return true;
     5         if (obj == null) return false;
     6         if (obj instanceof Animal){
     7             Animal animal = (Animal)obj;  // 类型强转
     8             // 因为name是String引用类型,所以直接进行equals比较就是进行值比较
     9             return animal.name.equals(this.name); 
    10         }
    11         return false;
    12     }

           然后我们再次运行上述的例子

            运行结果

           

           这回可以看到,重写了equals()方法之后,比较的结果就是值比较的结果了。

    3. 总结

        3.1 在基本类型中

              == 进行的是地址比较,不能进行equals()比较,因为equals()是Object中定义的方法,只有引用对象才能使用该方法

        3.2 在引用类型中:

              == 进行的是地址比较。equals()默认进行的是地址比较,如果使用的类重写了equals()方法的话,那就看他重写的源码使用的是什么比较。比如String类中就是进行值比较。

  • 相关阅读:
    2018
    线程的五大状态
    SQL 列转行与行转列
    python中元组(tuple)的拆包unkacping
    python字典的相关操作总结
    C语言使用typedef进行类型重定义
    C++中namespace的用法理解
    ping: unknown host 解决办法
    go环境变量配置liteide配置
    svn出现Authorization failed
  • 原文地址:https://www.cnblogs.com/pyexile/p/11426010.html
Copyright © 2020-2023  润新知