Java中equals与==的区别

发布时间 2023-07-19 10:20:34作者: codemcr

基础知识在对于我们的工作学习时,是非常重要的。
判断两个对象是否相等有两种方式:一种是利用 == 运算符,另一种是利用equals方法。

基本数据类型
  • int 整型
  • short 短整型
  • long 长整型
  • byte 字节型
  • char 字符型
  • float 单精度浮点型
  • double 双精度浮点型
  • boolean 布尔型
引用数据类型
  • 接口类型
  • 数组类型
  • 枚举类型
  • 注解类型
1.基本数据类型的比较

对于基本数据类型来说,只能通过“==”来进行比较两个变量的value值是否相同,这里举几个例子:

      int i1=10;
      int i2=10;
      System.out.println(i1==i2);        //true
      char test='a';
      char test1='a';
      System.out.println(test==test1);   //true
2.基本数据类型与引用类型对象的比较

当基本数据类型与引用类型比较时,“==”和equals两种方式都可以使用,且都是按照值比较

        int i1=130;
        Integer i2=new Integer(130);
        System.out.println(i2.equals(i1));       //true
        char test='a';
        Character test1=new Character('a');
        System.out.println(test==test1);         //true
3.引用类型对象与引用类型对象的比较(直接赋值)

下面六种包装类缓存池有默认内容:

包装类 缓存池范围
Byte -128~127
Short -128~127
Integer -128~127
Long -128~127
Character '\u0000'~'\u007F'
boolean true和false

当这六种包装类直接赋值缓存池范围内的值时,“==”指向的地址相同,否则地址不同,而equals方式由于各个包装类都重写了equals方法,判断值是否相同
例:

        Integer i1 =300;
        Integer i2=300;
        System.out.println(i2==i1);          //false
        System.out.println(i2.equals(i1));   //true
        i1=12;
        i2=12;
        System.out.println(i1==i2);          //true
        Character test='a';
        Character test1=new Character('a');
        System.out.println(test==test1);    //false
        System.out.println(test1.equals(test));    //true
        Double d1=12.0;
        Double d2=12.0;
        System.out.println(d1==d2);       //false

当直接将缓存池中的常量值赋给引用型对象时,对象从栈创建之后,直接引用的是在堆中常量池中值的地址,但是如果直接赋值的数据不在缓存池的范围内,将在堆中new 一个对象,同时在常量池中创建这个值,堆中的对象将指向这个常量池中的值。
Double和Float缓存池没有默认值

4.引用类型对象与引用类型对象的比较(new 对象)

当使用new对象时,将在堆创建一个对象,对象名指向这个对象,对象指向常量池中的值的地址。如果常量池存在这个值,将直接指向,否则将要创建一个常量值并指向。由于对象名指向的是对象的地址,所以“==”比较地址不同,重写的equals方法比较的是值是否相同。

        Integer i1 =new Integer(300);
        Integer i2=new Integer(300);
        System.out.println(i2==i1);      //false
        System.out.println(i2.equals(i1));    //true
        i1=new Integer(12);
        i2=new Integer(12);
        System.out.println(i1==i2);    //false
5.String的比较

在比较String类时,“==”比较的是地址,equals方法比较的是值是否相同,给大家看一下重写的String的equals源码:

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="123";
        String s2=new String ("123");
        System.out.println(s1==s2);      //false
        System.out.println(s1.equals(s2));    //true
        String s3="123";
        System.out.println(s1==s3);      //true

new和直接赋值的区别
直接赋值首先在常量池里边搜索是否存在,如果不存在的话,将创建一个常量值,并直接指向。
new的话,首先在堆中创建一个对象,对象在指向一个常量池的值,如果不存在,也是创建常量值,再将对象指向常量值。如果将常量直接给对象名,则对象名直接指向常量池的常量,而不是指向堆中的对象,对象在指向常量池的常量。

 String s1="123";
        String s2=new String ("123");    
        System.out.println(s1==s2);    //false
        System.out.println(s1.equals(s2));    //true
        s2="123";
        System.out.println(s1==s2);    //true
5.Object的比较

如果自己创建的类,没有继承其他包装类,则在比较对象时,“==”和equals方法相同都是比较地址是否相同,Object的源码:

public boolean equals(Object obj) {
        return (this == obj);      //比较地址是否相同
    }

例:

person person = new person();
        person person1 = new person();
        System.out.println(person1==person);    //false
        System.out.println(person1.equals(person));    //false