拆箱装箱以及double运算带来的陷阱
2019-02-12 本文已影响0人
miky_zheng
问题1:
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c == (a + b));
System.out.println(c.equals(a + b));
System.out.println(g == (a + b));
System.out.println(g.equals(a + b));
解释:
1.equals不处理数据类型转换
2.==不遇到算术运算时不会自动拆箱。但是为什么Integer.valueOf(3)==Integer.valueOf(3)结果为true,目前没有好的解释。但是注意:Integer.valueOf(321).equals(Integer.valueOf(321))结果为true。
编码时应注意避免自动拆箱装箱。
编译后的字节码如下:
Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(2);
Integer c = Integer.valueOf(3);
Integer d = Integer.valueOf(3);
Integer e = Integer.valueOf(321);
Integer f = Integer.valueOf(321);
Long g = Long.valueOf(3L);
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c.intValue() == a.intValue() + b.intValue());
System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));
System.out.println(g.longValue() == a.intValue() + b.intValue());
System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
公布上面答案结果:
System.out.println(c==d);//true
System.out.println(e==f);//false
System.out.println(c==(a+b));//true
System.out.println(c.equals(a+b));//true
System.out.println(g==(a+b));//true
System.out.println(g.equals(a+b)); //false
问题2:
double a = 0.1+0.2;
double b = 0.3;
System.out.println(a!=b);
// 输出结果:true;
double c = 0.2+0.2;
double d =0.4;
System.out.println(c==d);
// 输出结果 true;
解释:
0.1+0.2编译器在优化计算的时候,会变成:0.30000000000000004d([由javap解析字节码可查看]{https://www.jianshu.com/p/29e7739db599},见延伸部分)
0.2+0.2刚好是0.4.
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
5: iload_1
6: invokevirtual #6 // Method java/io/PrintStream.println:(I)V
9: ldc2_w #7 // double 0.30000000000000004d
12: dstore_2
13: ldc2_w #9 // double 0.3d
16: dstore 4
18: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;