java中equals和==的分析

来源:互联网 发布:域名举报需要多少人 编辑:程序博客网 时间:2024/06/13 10:30

前言

遇到过好多次比较大小和是否相等的,对equal和==了解一些,但是不是很全面,今天就整理一下,梳理一下,没事了就常看一下。

1.首先说“==”

我们知道所有的对象都拥有标志(内存地址)和状态(数据),“==”就是用来比较两个对象的内存地址的,内存地址相同,则为同一个对象,system.out.println(a == b)就为ture。

2.equals

equals的情况就有点复杂,复杂就复杂在子类对Object类中的equals()方法进行重写了。重写的理由就是为了方便我们进行数据的比较。

超类Object中有equals()方法,该源码为:

public boolean equals(Object obj) {   return (this == obj);}



但是在String、Math、Integer、Double……等类中是重写了equals方法。

在String中的源码为

public boolean equals(Object anObject) {    if (this == anObject) {    return true;}if (anObject instanceof String) {    String anotherString = (String)anObject;    int n = count;    if (n == anotherString.count) {        char v1[] = value;        char v2[] = anotherString.value;        int i = offset;        int j = anotherString.offset;        while (n-- != 0) {           if (v1[i++] != v2[j++])           return false;       }    return true;    }}return false;}


在这段代码if (v1[i++] != v2[j++])return false;可以看出String的equals()方法是进行内容的比较,而不是地址的比较。
至于其它的封装类也差不多,但是我还想对Integer在说点。

先看代码

Integer a = 127;Integer b = 127;Integer c = 128;Integer d = 128;System.out.println(a.equals(b));//①System.out.println(c.equals(d));//②System.out.println(a==b);//③System.out.println(c==d);//④


结果是

true //①
true //②
true //③
false //④

对于①和②很好理解,因为Integer对equals进行重写了吗,比较的是值的大小,自然就相等,为true。

③和④怎么就一个true,一个为false呢,这里也涉及到了另一个概念,自动装箱。Integer a = Integer.valueOf(127);Integer b = Integer.valueOf(127);

设计到valueOf函数了,看一下源代码吧

 public static Integer valueOf(int i) {       assert IntegerCache.high >= 127;       if (i >= IntegerCache.low && i <= IntegerCache.high)           return IntegerCache.cache[i + (-IntegerCache.low)];       return new Integer(i); }


对于-128到127之间的数会进行缓存,在一次定义变量时会从缓存中取,不用new新对象,在-128到127之外的数,是会进行new一个新的对象。所以③为ture,④为false了。

在出一个题吧

Integer a = 288; int d = 288;System.out.println(d == a);


这个结果为true,这个涉及到了Integer的拆箱,基本类型是存储在栈中,包装类型是存储在堆中,当int和Integer在一起时,Integer会自动拆箱,变成int类型,而双等于永远是比较对象/基本类型存储的引用的值,所以这个例子结果为true。

在 java 中进行比较,我们需要根据比较的类型来选择合适的比较方式:
1) 对象域,使用 equals 方法 。
2) 类型安全的枚举,使用 equals 或== 。
3) 可能为 null 的对象域 : 使用 == 和 equals 。
4) 数组域 : 使用 Arrays.equals 。
5)除 float 和 double 外的原始数据类型 : 使用 == 。
6) float 类型: 使用 Float.foatToIntBits 转换成 int 类型,然后使用==。
7) double 类型: 使用 Double.doubleToLongBit 转换成 long 类型,然后使用==。

1 0
原创粉丝点击