equals与==区别

来源:互联网 发布:人工智能行业报告 36kr 编辑:程序博客网 时间:2024/05/21 17:01

1.基本类型

        因为java中的8中基本类型都不是对象,不存在equals方法,只能用“==”比较内容。

2.对象

        在Object中,equals方法和“==”都是比较对象在堆内的首地址,即判断两个引用变量是否指向同一个对象。

        除非重写了equals方法。

3.包装类型

        在包装类型中,都重写了equals方法,所以比较的是对象的内容是否相等。而“==”比较的是地址。

        另外除了8种包装类型,String,Date也重写了equals方法

4.example

 public static void main(String[] args) {                 Integer a = 1;        Integer b = 2;        Integer c = 3;        Integer d = 3;        Integer e = 321;        Integer f = 321;        Long g = 3L;        Long h = 2L;        String str1="hello";        String str2="hello";        String str3=new String("hello");        String str4=new String("hello");        String str5="he"+new String("llo");        StringBuffer str6=new StringBuffer("hello");        StringBuffer str7=new StringBuffer("hello");        Object o1=new Object();        Object o2=new Object();                 System.out.println(c==d);             //1 true        System.out.println(e==f);             //2 false        System.out.println(c==(a+b));         //3 true        System.out.println(c.equals(a+b));    //4 true        System.out.println(g==(a+b));         //5 true        System.out.println(g.equals(a+b));    //6 false        System.out.println(g.equals(a+h));    //7 true 以上包装类型        System.out.println(str1==str2);       //8 true        System.out.println(str1.equals(str2));//9 true        System.out.println(str1==str3);       //10 false        System.out.println(str1.equals(str3));//11 true        System.out.println(str3==str4);       //12 false        System.out.println(str4==str5);       //13 false        System.out.println(str1==str5);       //14 false        System.out.println(str1.equals(str5));//15 true        System.out.println(str6==str7);       //16 false        System.out.println(str6.equals(str7));//17 false        System.out.println(o1==o2);           //18 false        System.out.println(o1.equals(o2));    //18 false            }
结果解析:

        1-7 考虑是数据的包装类型,值得注意的是==原本比较的是引用变量是否指向同一个对象,但是进行运算时a+b,会自动拆箱,因此==比较的是内容。而如果时equals(a+b),则会先进行拆箱,运算后再装箱。Integer的缓冲池是[-128,127],如果在此范围之内,返回同一引用,否则,要重新new对象。所以1true,2false ,3数值内容相同true,4触发自动拆箱运算再装箱,比较的值true ,5 值同true

public boolean equals(Object obj) {if (obj instanceof Long) {    return value == ((Long)obj).longValue();}return false;    }
以上为Long重写的equals方法。6  a+b装箱为Integer 非Long,false , 7 a+h 精度升级,所以封装为Long。

        8.常量赋值字符串时,会创建一个字符串缓冲池。所以赋值str2时,会先去字符串缓冲池中查找相同的对象,如果有直接返回引用,没有再创建。true, 9 true 10 str3用的new,重新申请的空间,false  12重新new,申请了两个不同的空间 false 17 StringBuffer 没有重写equals方法,继承了Object中的equals,比较的是堆内的首地址false

5.补充

        1.System.out.println(str1==str3.intern());    --->true  原因:intern方法返回“hello”,但是进行了处理,去字符串缓冲池中查找“hello”,如果存在直接返回,不存在则在缓冲池中创建,然后再返回引用。

        2. Float f1=1f;Float f2=2f;  System.out.println(f1==f2); --->false 原因8种包装类型中long和float都是没有缓存池的。因为比起Integer来说在一定的范围内,该类型所持有的数量是不一定的。

0 0