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

一、传统认知

运算

基本数据类型比较的对象

引用数据类型比较的对象

==

堆内存空间

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的开发人员也知道这个问题,于是他们提供了这样的解决方法:

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

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

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

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实例,不会重新创建对象,而是重用已经存在的对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值