10.0和10进行==与equals

首先这是由一道面试题来的总结

面试题中要求我对Float,Double,float,double,int型的值,进行==和equals的选项判别### 别看这是一道很小的题,自己平时稍不注意,这道题就会出错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package it.hacker.string;

/**
* @author wqh
* @date 18-10-28
*/
public class NumbersEquals {

public static void main(String[] args) {
float floa = 10.0f;
double doub = 10.0;
Float f = floa;
Double d = doub;
int in = 10;
if (doub==floa) {

System.out.println("doub==floa");
}
if (floa==d){
System.out.println("floa==d");

}
if (floa==in){
System.out.println("floa==in");
}
if (doub==f){
System.out.println("doub==f");
}
/**
* 除了这个是false其余的全是true
*/
if (d.equals(f)){
System.out.println("d.equals(f)");
}

if (10.0==10){
System.out.println("10.0==10");
}
}


}

分析

其实反编译一下这个文件就可以很明显的看出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) annotate
// Source File Name: NumbersEquals.java

package it.hacker.string;

import java.io.PrintStream;

public class NumbersEquals
{

public NumbersEquals()
{
// 0 0:aload_0
// 1 1:invokespecial #1 <Method void Object()>
// 2 4:return
}

public static void main(String args[])
{
float floa = 10F;
// 0 0:ldc1 #2 <Float 10F>
// 1 2:fstore_1
double doub = 10D;
// 2 3:ldc2w #3 <Double 10D>
// 3 6:dstore_2
Float f = Float.valueOf(floa);
// 4 7:fload_1
// 5 8:invokestatic #5 <Method Float Float.valueOf(float)>
// 6 11:astore 4
Double d = Double.valueOf(doub);
// 7 13:dload_2
// 8 14:invokestatic #6 <Method Double Double.valueOf(double)>
// 9 17:astore 5
int in = 10;
// 10 19:bipush 10
// 11 21:istore 6
if(doub == (double)floa)
//* 12 23:dload_2
//* 13 24:fload_1
//* 14 25:f2d
//* 15 26:dcmpl
//* 16 27:ifne 38
System.out.println("doub==floa");
// 17 30:getstatic #7 <Field PrintStream System.out>
// 18 33:ldc1 #8 <String "doub==floa">
// 19 35:invokevirtual #9 <Method void PrintStream.println(String)>
if((double)floa == d.doubleValue())
//* 20 38:fload_1
//* 21 39:f2d
//* 22 40:aload 5
//* 23 42:invokevirtual #10 <Method double Double.doubleValue()>
//* 24 45:dcmpl
//* 25 46:ifne 57
System.out.println("floa==d");
// 26 49:getstatic #7 <Field PrintStream System.out>
// 27 52:ldc1 #11 <String "floa==d">
// 28 54:invokevirtual #9 <Method void PrintStream.println(String)>
if(floa == (float)in)
//* 29 57:fload_1
//* 30 58:iload 6
//* 31 60:i2f
//* 32 61:fcmpl
//* 33 62:ifne 73
System.out.println("floa==in");
// 34 65:getstatic #7 <Field PrintStream System.out>
// 35 68:ldc1 #12 <String "floa==in">
// 36 70:invokevirtual #9 <Method void PrintStream.println(String)>
if(doub == (double)f.floatValue())
//* 37 73:dload_2
//* 38 74:aload 4
//* 39 76:invokevirtual #13 <Method float Float.floatValue()>
//* 40 79:f2d
//* 41 80:dcmpl
//* 42 81:ifne 92
System.out.println("doub==f");
// 43 84:getstatic #7 <Field PrintStream System.out>
// 44 87:ldc1 #14 <String "doub==f">
// 45 89:invokevirtual #9 <Method void PrintStream.println(String)>
if(d.equals(f))
//* 46 92:aload 5
//* 47 94:aload 4
//* 48 96:invokevirtual #15 <Method boolean Double.equals(Object)>
//* 49 99:ifeq 110
System.out.println("d.equals(f)");
// 50 102:getstatic #7 <Field PrintStream System.out>
// 51 105:ldc1 #16 <String "d.equals(f)">
// 52 107:invokevirtual #9 <Method void PrintStream.println(String)>
System.out.println("10.0==10");
// 53 110:getstatic #7 <Field PrintStream System.out>
// 54 113:ldc1 #17 <String "10.0==10">
// 55 115:invokevirtual #9 <Method void PrintStream.println(String)>
// 56 118:return
}
}

稍微总结一下

  • ==判断的是两个对象是否是同一个对象,基本数据类型比较的是值,引用数据类型比的是地址
  • equals()的也是判断两个对象是不是同一个对象,但是在类中覆盖了object类中的equals方法的时候,一般来说是比较的内容,这个是根据重写的内容来看的,如果没有重写的话,这个是直接调用的object的equals方法,而这个是直接根据==进行的判断

    1
    2
    3
    public boolean equals(Object obj) {
    return (this == obj);
    }
  • 最后从反编译的文件中可以看到这个其实是把类型做了强转,之后再进行的比较,floa == (float)in这个就是很明显的例子,既然做了强转那么两个值就是一样的,当然返回的是true

  • 其实这其中应该还有一个问题,这个问题就是强转所引出的问题。整型转化为二进制数很好转,但是小数转就有可能出现无限循环,整形的10进制数直接除以2,但是小数好像是直接乘以2,一直乘到没有小数为止.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    float test = 10.1f;
    double aaa = 0;
    aaa = test;
    System.out.println(aaa);
    //10.100000381469727
    float test = 10.0f;
    double aaa = 0;
    aaa = test;
    System.out.println(aaa);
    //10.0
  • 其中可以看到一点的是10=10.0那个判断在字节码里面是没有if了,是具体的值,编译器在编译的时候直接算出来了,直接给了结果。

0%