欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java常识1:弄清楚equals()和“==”

程序员文章站 2022-07-12 16:54:24
...

一、传统认知

运算

基本数据类型比较的对象

引用数据类型比较的对象

==

堆内存空间

equals

默认堆内存空间,覆写的方法除外

二、通过程序找问题

import com.leon.java.reflect.Person;

class Dog{
    private String name ;
    Dog(){}
    Dog(String name){
        this.name = name;
    }
}

public class EqualsDemo<T> {

     void test(T t1,T t2){
        System.out.println("t1是否==t2:" + (t1 == t2));
        System.out.println("t1是否equals t2:" + (t1.equals(t2)));
    }

    public static void main(String[] args) {

        // == 比较 基本类型
        System.out.println("\n--------比较基本类型-------");

        System.out.println("\n1.比较Byte");
        new EqualsDemo<Byte>().test((byte)123,(byte)123);

        System.out.println("\n2.比较Short");
        new EqualsDemo<Short>().test((short)123,(short)123);

        System.out.println("\n3.比较Integer");
        new EqualsDemo<Integer>().test(1,1);

        System.out.println("\n4.比较Long");
        new EqualsDemo<Long>().test(123L,123L);

        System.out.println("\n5.比较Float");
        new EqualsDemo<Float>().test(1.4f,1.4f);

        System.out.println("\n6.比较Double");
        new EqualsDemo<Double>().test(1.433333,1.433333);

        System.out.println("\n7.比较char");
        new EqualsDemo<Character>().test('a','a');

        System.out.println("\n8.比较Boolean");
        new EqualsDemo<Boolean>().test(true,true);

        //发现的问题1:浮点型两个“相同的数” == 比较结果不同。解决方法:浮点型数据比较是否相等时,转化成包装类型,使用equals进行比较。

        //比较引用类型
        System.out.println("\n--------比较引用类型-------");

        Dog d1 = new Dog("旺旺");
        Dog d2 = new Dog("旺旺");
        System.out.println("\n比较自定义的Dog类");
        new EqualsDemo<Dog>().test(d1,d2);

        System.out.println("\n比较String");
        new EqualsDemo<String>().test("aaa","aaa");

        //发现问题:String是引用类型,==比较引用类型时,比较的应该是地址才对。为什么在这里两个String对象的比较结果是true。
    }
}

JDK1.8下输出结果为:

--------比较基本类型-------

1.比较Byte
t1是否==t2:true
t1是否equals t2:true

2.比较Short
t1是否==t2:true
t1是否equals t2:true

3.比较Integer
t1是否==t2:true
t1是否equals t2:true

4.比较Long
t1是否==t2:true
t1是否equals t2:true

5.比较Float
t1是否==t2:false
t1是否equals t2:true

6.比较Double
t1是否==t2:false
t1是否equals t2:true

7.比较char
t1是否==t2:true
t1是否equals t2:true

8.比较Boolean
t1是否==t2:true
t1是否equals t2:true

--------比较引用类型-------

比较自定义的Dog类
t1是否==t2:false
t1是否equals t2:false

比较String
t1是否==t2:true
t1是否equals t2:true

这里我们不难发现两个问题:

       问题1:浮点型两个“相同的数” == 比较结果为什么不同?

       问题2:String是引用类型,==比较引用类型时,比较的应该是地址才对。为什么在这里两个String对象的比较结果是true?

三、解决问题

       1.浮点型数据判断是否相等

答:这个问题的由来比较古老,是浮点型这种数据类型的设计导致了这种情况。当然,JDK的开发人员也知道这个问题,于是他们提供了这样的解决方法:

java常识1:弄清楚equals()和“==”

意思是:只要参数传入的对象是Double类型,且当前对象和传入对象的“doubleToLongBits()”相同即认定为两者相等。

我们来看doubleToLongBits(double value)方法。

java常识1:弄清楚equals()和“==”

第一行就调用了另一个方法:

doubleToRawLongBits();

        java.lang.Double.doubleToRawLongBits() 方法返回根据IEEE754浮点“双精度格式”位布局,不是非数字(NaN)值,返回指定浮点值的表示。它包括以下要点:

  •    如果参数为正无穷大,其结果是 0x7ff0000000000000L.
  •    如果参数为负无穷大,其结果是 0xfff0000000000000L.
  •    如果参数为NaN,那么结果是长整型表示实际NaN值。doubleToLongBits方法不同,doubleToRawLongBits不垮所有的位模式NaN编码为一个单一的“规范”NaN值。

简单理解:

上面的内容有点多不想看,可以简单理解为:Double的equals()方法是通过将double型转换成long型变量,来进行数值比较的。

 

2.String是引用类型,==比较引用类型时,比较的应该是堆内存才对。为什么在这里两个String对象的比较结果是true?

答:java代码实际的执行引擎是jvm,jvm为String型变量提供了缓存机制,只要内容相同的String实例,不会重新创建对象,而是重用已经存在的对象。

上一篇: Linux防火墙

下一篇: linux防火墙