Java中equals和 == 的区别

==:
== 比较的是内存中存放的对象的堆内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
==两边必须是同一数据类型才可以比较。
但如果是具体的阿拉伯数字的比较,则比较的具体的值是否相等,如int 10 == double 10.0 则为true。
equals:
equals用来比较的是两个对象的内容是否相等,equals适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。
但是基本数据类型无法调用equals方法。
之所以equals能进行对象的内容判断,原因就在于这些类(像String、Integer等类)对equals进行了重写。
1、下面说一下equals与==对于基本数据类型和包装类的判断:、

int a =10; double b = 10.0;
System.out.println(a == b);//true

在上述基本数据类型进行大小判断时,int类型会默认转成double类型再进行大小的比较,所以int 10,double 10.0,long 10L 的大小都相等,故返回true。

  Integer c = 10, d = 10,e = 130, f = 130;
    System.out.println(c == d);//true
     System.out.println(c.equals(d));//true
    System.out.println(e == f);//false
    System.out.println(e.equals(f));//true

根据上述显示结果可知,c与d进行==比较的时候,结果为true,而e与f进行==比较的时候,结果为false。
原因是:通过源码可以得知,在执行Ingeter c = 10 的时候,实际上执行的是Ingeter c = Integer.valueOf(10)。
因为Integer中的valueOf()方法会先进行一次数据大小判断,如果大小在[-128,127]之间,则直接返回IntegerCache中cache[]数组缓冲区的值。
如果范围超出[-128,127],则返回new Integer(),而new出来的两个对象地址值并不相同,故结果为false。
equals方法在Integer中进行了重写,所以equals方法是判断两者内容是否相同,故为true。

     int i = 130;
    System.out.println(e == i);//true

当基本数据类型和包装类进行==判断的时候,会先自动拆箱,然后再进行数值的比较,故返回true。

Integer g = 20; Double h = 20.0;
System.out.println(g.equals(h));//false

因为Integer的equals()的方法,与Double进行比较的时候,会先判断一下传入的参数类型是否为Integer类型,如果不是,则直接返回false。
2、equals与==对String类型的判断:

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

根据上述发现,s1 == s2 结果为true,这是因为java有常量池,存储所有的字符串常量,当给String直接赋值时,会首先在常量池中查找是否有”aaa”这个常量,如果没有,就创建一个”aaa”,然后复制给s1。
在创建s2时,java同样会在常量池中查找”aaa”,因为常量池中已经有”aaa”,所以不会创建新的”aaa”,将地址直接赋给s2。
所以s1,s2使用的同一地址值,故返回true。

  String s3 = new String(s1);
  System.out.println(s2 == s3);//false
  System.out.println(s2.equals(s3));//true

s3所创建的对象是new出来的,保存在堆内存中,所以地址值与s2不相同,故返回false。
而equals在String中进行了重写,比较的是两个字符串内容,故返回true。
3、equals与==对自定义类型的判断:
①创建一个person类,在Person对象中设置Sring类型的ID为888。并创建两个person对象。

        Person p1 = new Person();
        Person p2 = new Person();
        System.out.println(p1 == p2);//①false
        System.out.println(p1.equals(p2));//②false
        System.out.println(p1.id.equals(p2.id));//③true
        System.out.println(p1.equals(p2));//④true -->在Person中重写equals方法后

p1与p2是在堆内存中的两个不同的对象,所以用==判断地址值,显然是false。
②自定义数据类型未经过重写equals,直接继承了Object的equals方法,判断的是两个对象内存的地址值。
而引用数据类型中equals比较的是内容,是因为在引用对象中重写了equals方法。
③ 此处直接比较id是否相同。故返回值为true。
④在Person中重写equals方法后返回值为true,这是因为重写equals方法后比较的是id是否相同。故返回值为true。
另外,equals的五个重要特点:
1 自反性:对任意引用值X,x.equals(x)的返回值一定为true;
  2 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
  3 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true ;
  4 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变;
  5 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false 。
  

你可能感兴趣的:(Java中equals和 == 的区别)