godtrue

前言:按理说这种错误,工作多年之后就不应该再犯的,不过实际工作中我遇到过两次,工作n年的同事还是犯了,所以,在此记上一笔以作警醒。还是先尝栗子,再下结论。

1:使用BigDecimal类,实际中也是经常用的,不过相对来说使用此类时犯的错误会少一点

package com.jd.test.integer;

import java.math.BigDecimal;

public class TestBigDecimalMain {
    public static void main(String args[]){
        BigDecimal _BigDecimal1 = new BigDecimal(99);
        BigDecimal _BigDecimal2 = new BigDecimal(99);

        System.out.println("_BigDecimal1 hashCode is :"+_BigDecimal1.hashCode()+"\n_BigDecimal2 hashCode is :"+_BigDecimal2.hashCode());
        System.out.println("_BigDecimal1 identityHashCode is :"+System.identityHashCode(_BigDecimal1)+"\n_BigDecimal2 identityHashCode is :"+System.identityHashCode(_BigDecimal2));

        //包装类型的==比较,赋值时采用的是创建对应的对象的方式
        System.out.println("_BigDecimal1==_BigDecimal2 is : "+(_BigDecimal1==_BigDecimal2));//false,注意:这里是false,也就是说不能使用这种比较方式
        //包装类型的equals比较
        System.out.println("_BigDecimal1.equals(_BigDecimal2) is : "+(_BigDecimal1.equals(_BigDecimal2)));//true
    }
}

2:使用Double类,特别是_Double1==_Double2相比较时,更容易出错

package com.jd.test.integer;

public class TestDoubleMain {
    public static void main(String args[]){
        double double1 = 99;
        double double2 = 99;
        Double _Double1 = 99D;
        Double _Double2 = 99D;
        Double _Double3 = new Double(99);
        Double _Double4 = new Double(99);

        System.out.println("double1 identityHashCode is :"+System.identityHashCode(double1)+"\ndouble2 identityHashCode is :"+System.identityHashCode(double2));

        System.out.println("_Double1 hashCode is :"+_Double1.hashCode()+"\n_Double2 hashCode is :"+_Double2.hashCode());
        System.out.println("_Double1 identityHashCode is :"+System.identityHashCode(_Double1)+"\n_Double2 identityHashCode is :"+System.identityHashCode(_Double2));

        System.out.println("_Double3 hashCode is :"+_Double3.hashCode()+"\n_Double4 hashCode is :"+_Double4.hashCode());
        System.out.println("_Double3 identityHashCode is :"+System.identityHashCode(_Double3)+"\n_Double4 identityHashCode is :"+System.identityHashCode(_Double4));


        //基本类型的==比较
        System.out.println("double1==double2 is : "+(double1==double2));//true
        //基本类型和包装类型的==比较
        System.out.println("double1==_Double1 is : "+(double1==_Double1));//true
//        System.out.println("_Double1==double1 is : "+(_Double1==double1));//true
        System.out.println("double1==_Double3 is : "+(double1==_Double3));//true
//        System.out.println("_Double3==double1 is : "+(_Double3==double1));//true
        //包装类型的==比较,赋值时采用的是直接赋值的方式
        System.out.println("_Double1==_Double2 is : "+(_Double1==_Double2));//false,注意:这里是false,也就是说不能使用这种比较方式
        //包装类型的==比较,赋值时采用的是创建对应的对象的方式
        System.out.println("_Double1==_Double3 is : "+(_Double1==_Double3));//false,注意:这里是false,也就是说不能使用这种比较方式
        System.out.println("_Double3==_Double4 is : "+(_Double3==_Double4));//false,注意:这里是false,也就是说不能使用这种比较方式
        //基本类型和包装类型的equals比较
        System.out.println("_Double1.equals(double1) is : "+(_Double1.equals(double1)));//true
        //包装类型的equals比较
        System.out.println("_Double1.equals(_Double2) is : "+(_Double1.equals(_Double2)));//true
        System.out.println("_Double3.equals(_Double1) is : "+(_Double3.equals(_Double1)));//true
        System.out.println("_Double3.equals(_Double4) is : "+(_Double3.equals(_Double4)));//true

        System.out.println(System.identityHashCode(_Double1)+"   "+System.identityHashCode(_Double2));//true
    }
}

3:使用Float类,特别是_Float1==_Float2相比较时,更容易出错

package com.jd.test.integer;

public class TestFloatMain {
    public static void main(String args[]){
        float float1 = 99;
        float float2 = 99;
        Float _Float1 = 99F;
        Float _Float2 = 99F;
        Float _Float3 = new Float(99);
        Float _Float4 = new Float(99);

        System.out.println("float1 identityHashCode is :"+System.identityHashCode(float1)+"\nfloat2 identityHashCode is :"+System.identityHashCode(float2));

        System.out.println("_Float1 hashCode is :"+_Float1.hashCode()+"\n_Float2 hashCode is :"+_Float2.hashCode());
        System.out.println("_Float1 identityHashCode is :"+System.identityHashCode(_Float1)+"\n_Float2 identityHashCode is :"+System.identityHashCode(_Float2));

        System.out.println("_Float3 hashCode is :"+_Float3.hashCode()+"\n_Float4 hashCode is :"+_Float4.hashCode());
        System.out.println("_Float3 identityHashCode is :"+System.identityHashCode(_Float3)+"\n_Float4 identityHashCode is :"+System.identityHashCode(_Float4));


        //基本类型的==比较
        System.out.println("float1==float2 is : "+(float1==float2));//true
        //基本类型和包装类型的==比较
        System.out.println("float1==_Float1 is : "+(float1==_Float1));//true
//        System.out.println("_Float1==float1 is : "+(_Float1==float1));//true
        System.out.println("float1==_Float3 is : "+(float1==_Float3));//true
//        System.out.println("_Float3==float1 is : "+(_Float3==float1));//true
        //包装类型的==比较,赋值时采用的是直接赋值的方式
        System.out.println("_Float1==_Float2 is : "+(_Float1==_Float2));//false,注意:这里是false,也就说不能使用这种比较方式
        //包装类型的==比较,赋值时采用的是创建对应的对象的方式
        System.out.println("_Float1==_Float3 is : "+(_Float1==_Float3));//false,注意:这里是false,也就说不能使用这种比较方式
        System.out.println("_Float3==_Float4 is : "+(_Float3==_Float4));//false,注意:这里是false,也就说不能使用这种比较方式
        //基本类型和包装类型的equals比较
        System.out.println("_Float1.equals(float1) is : "+(_Float1.equals(float1)));//true
        //包装类型的equals比较
        System.out.println("_Float1.equals(_Float2) is : "+(_Float1.equals(_Float2)));//true
        System.out.println("_Float3.equals(_Float1) is : "+(_Float3.equals(_Float1)));//true
        System.out.println("_Float3.equals(_Float4) is : "+(_Float3.equals(_Float4)));//true
    }
}

4:使用Integer类,特别是integer1==integer3相比较时,更容易出错

package com.jd.test.integer;

public class TestIntegerMain {
    public static void main(String args[]){
        int int1 = 99;
        int int2 = 99;
        Integer _Integer1 = 99;
        Integer _Integer2 = 99;
        Integer _Integer3 = new Integer(99);
        Integer _Integer4 = new Integer(99);

        System.out.println("int1 identityHashCode is :"+System.identityHashCode(int1)+"\nint2 identityHashCode is :"+System.identityHashCode(int2));

        System.out.println("_Integer1 hashCode is :"+_Integer1.hashCode()+"\n_Integer2 hashCode is :"+_Integer2.hashCode());
        System.out.println("_Integer1 identityHashCode is :"+System.identityHashCode(_Integer1)+"\n_Integer2 identityHashCode is :"+System.identityHashCode(_Integer2));

        System.out.println("_Integer3 hashCode is :"+_Integer3.hashCode()+"\n_Integer4 hashCode is :"+_Integer4.hashCode());
        System.out.println("_Integer3 identityHashCode is :"+System.identityHashCode(_Integer3)+"\n_Integer4 identityHashCode is :"+System.identityHashCode(_Integer4));

        //基本类型的==比较
        System.out.println("int1==int2 is : "+(int1==int2));//true
        //基本类型和包装类型的==比较
        System.out.println("int1==_Integer1 is : "+(int1==_Integer1));//true
//        System.out.println("_Integer1==int1 is : "+(_Integer1==int1));//true
        System.out.println("int1==_Integer3 is : "+(int1==_Integer3));//true
//        System.out.println("_Integer3==int1 is : "+(_Integer3==int1));//true
        //包装类型的==比较,赋值时采用的是直接赋值的方式
        System.out.println("_Integer1==_Integer2 is : "+(_Integer1==_Integer2));//true
        //包装类型的==比较,赋值时采用的是创建对应的对象的方式
        System.out.println("_Integer1==_Integer3 is : "+(_Integer1==_Integer3));//false,注意:这里是false,也就说不能使用这种比较方式
        System.out.println("_Integer3==_Integer4 is : "+(_Integer3==_Integer4));//false,注意:这里是false,也就说不能使用这种比较方式
        //基本类型和包装类型的equals比较
        System.out.println("_Integer1.equals(int1) is : "+(_Integer1.equals(int1)));//true
        //包装类型的equals比较
        System.out.println("_Integer1.equals(_Integer2) is : "+(_Integer1.equals(_Integer2)));//true
        System.out.println("_Integer3.equals(_Integer1) is : "+(_Integer3.equals(_Integer1)));//true
        System.out.println("_Integer3.equals(int1) is : "+(_Integer3.equals(int1)));//true
        System.out.println("_Integer3.equals(_Integer4) is : "+(_Integer3.equals(_Integer4)));//true
    }
}

5:使用Long类,特别是_Long1==_Long3相比较时,更容易出错

package com.jd.test.integer;

public class TestLongMain {
    public static void main(String args[]){
        long long1 = 99;
        long long2 = 99;;
        Long _Long1 = 99L;
        Long _Long2 = 99L;
        Long _Long3 = new Long(99);
        Long _Long4 = new Long(99);

        System.out.println("long1 identityHashCode is :"+System.identityHashCode(long1)+"\nlong2 identityHashCode is :"+System.identityHashCode(long2));

        System.out.println("_Long1 hashCode is :"+_Long1.hashCode()+"\n_Long2 hashCode is :"+_Long2.hashCode());
        System.out.println("_Long1 identityHashCode is :"+System.identityHashCode(_Long1)+"\n_Long2 identityHashCode is :"+System.identityHashCode(_Long2));

        System.out.println("_Long3 hashCode is :"+_Long3.hashCode()+"\n_Long4 hashCode is :"+_Long4.hashCode());
        System.out.println("_Long3 identityHashCode is :"+System.identityHashCode(_Long3)+"\n_Long4 identityHashCode is :"+System.identityHashCode(_Long4));

        //基本类型的==比较
        System.out.println("long1==long2 is : "+(long1==long2));//true
        //基本类型和包装类型的==比较
        System.out.println("long1==_Long1 is : "+(long1==_Long1));//true
//        System.out.println("_Long1==long1 is : "+(_Long1==long1));//true
        System.out.println("long1==_Long3 is : "+(long1==_Long3));//true
//        System.out.println("_Long3==long1 is : "+(_Long3==long1));//true
        //包装类型的==比较,赋值时采用的是直接赋值的方式
        System.out.println("_Long1==_Long2 is : "+(_Long1==_Long2));//true
        //包装类型的==比较,赋值时采用的是创建对应的对象的方式
        System.out.println("_Long1==_Long3 is : "+(_Long1==_Long3));//false,注意:这里是false,也就是说不能使用这种比较方式
        System.out.println("_Long3==_Long4 is : "+(_Long3==_Long4));//false,注意:这里是false,也就是说不能使用这种比较方式
        //基本类型和包装类型的equals比较
        System.out.println("_Long1.equals(long1) is : "+(_Long1.equals(long1)));//true
        //包装类型的equals比较
        System.out.println("_Long1.equals(_Long2) is : "+(_Long1.equals(_Long2)));//true
        System.out.println("_Long3.equals(_Long1) is : "+(_Long3.equals(_Long1)));//true
        System.out.println("_Long3.equals(_Long4) is : "+(_Long3.equals(_Long4)));//true
    }
}

 6:结论

     6-1:当变量声明时使用的全部都是基本数据类型,使用==比较是没问题的,当然,也只能使用==看看他们是否相等,此时比较的是变量的值是否相等

     6-2:当变量声明时全部或者部分使用了封装类型,使用==比较可能得不到我们预期的效果,建议一定使用equals方法,基本类型的包装类型类,都重写了equals方法,比较的是对象的内容是否相等,对于数据类型而言,就是他们的值是否相等

     如果想问为什么这样呢?请参看==和equals的简单比较吧!

     如果你将代码执行起来,观察了一下的话,还是有些问题没解释清楚的,比如:为什么 int int1=99;int int2=99;int1和int2的identityHashCode是一样的哪?为什么float float1=99;float float2=99;float1和float2的identityHashCode是不一样的哪?那就需要了解identityHashCode的生成规则了,需要了解一下java的内存地址分配规则了。为什么double1==_Double1 is : true,但是他们的identityHashCode却不相等哪?这需要了解一下基本数据类型和封装类型,自动拆箱和自动装箱的相关知识点了。

posted on 2017-02-08 20:23  godtrue  阅读(543)  评论(1编辑  收藏  举报