源码分析equlas和==的区别

对于“==”是直接比较的两个对象的堆内存地址,如果相等,则说明这两个引用实际是指向同一个对象地址的

对于基本数据类型(byte,short,char,int,float,double,long,boolean)来说,他们是作为常量在方法区中的常量池里面以HashSet策略存储起来的,对于这样的字符串 "123" 也是相同的道理,在常量池中,一个常量只会对应一个地址,因此不管是再多的 123,"123" 这样的数据都只会存储一个地址,所以所有他们的引用都是指向的同一块地址,因此基本数据类型和String常量是可以直接通过==来直接比较的。

另外,对于基本数据的包装类型(Byte, Short, Character,Integer,Float, Double,Long,  Boolean)除了Float和Double之外,其他的六种都是实现了常量池的,因此对于这些数据类型而言,一般我们也可以直接通过==来判断是否相等。那么再出一个问题考考大家 ↓

猜猜看,结果是啥?。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

结果是 true,false。没想到吧!其实是因为 Integer 在常量池中的存储范围为[-128,127],127在这范围内,因此是直接存储于常量池的,而128不在这范围内,所以会在堆内存中创建一个新的对象来保存这个值,所以m,n分别指向了两个不同的对象地址,故而导致了不相等。
————————————————

对于equals方法,基类object对象内部的实现是直接调用“==”,所以此时两者并无差别,但是我们可以重写equals方法

//Object class的源码-jdk1.8
public boolean equals(Object obj) {
        return (this == obj);
    }

string对象自己就重写了equals方法,

//String class的源码-jdk1.8

/** The value is used for character storage. */
    private final char value[];

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;//内存地址相同表示同一个对象直接返回true
        }
        if (anObject instanceof String) {//若内存地址不同,那么接着判断值是否相同,相同返回true
            String anotherString = (String)anObject;
            int n = value.length;//对象的值
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;//待判断的参数的值
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;//不同返回false
                    i++;
                }
                return true;
            }
        }
        return false;//走到这说明(anObject instanceof String)为false,则判断的结果肯定不同
    }

instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:

1

boolean result = obj instanceof Class

  其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。

  注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定

1、obj 必须为引用类型,不能是基本类型

1

2

3

int i = 0;

System.out.println(i instanceof Integer);//编译不通过

System.out.println(i instanceof Object);//编译不通过

  instanceof 运算符只能用作对象的判断。

回到顶部

2、obj 为 null

1

System.out.println(null instanceof Object);//false

  关于 null 类型的描述在官方文档:https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.1 有一些介绍。一般我们知道Java分为两种数据类型,一种是基本数据类型,有八个分别是 byte  short  int  long  float  double  char boolean,一种是引用类型,包括类,接口,数组等等。而Java中还有一种特殊的 null 类型,该类型没有名字,所以不可能声明为 null 类型的变量或者转换为 null 类型,null 引用是 null 类型表达式唯一可能的值,null 引用也可以转换为任意引用类型。我们不需要对 null 类型有多深刻的了解,我们只需要知道 null 是可以成为任意引用类型的特殊符号

  在 JavaSE规范 中对 instanceof 运算符的规定就是:如果 obj 为 null,那么将返回 false。


参考:

https://blog.csdn.net/lcsy000/article/details/82782864

https://www.cnblogs.com/ysocean/p/8486500.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值