== 和 equals()方法的区别

代码1:

public static void main(String[] args) {
        int a = 10;
        int b = 10;
        Integer c = 10;
        Integer d = 10;
        Integer e = 128;
        Integer f = 128;
        System.out.println(a == b);
        System.out.println(c == d);
        System.out.println(e == f);
}

结果:


代码2:

public static void main(String[] args) {
        Integer a = new Integer(10);
        Integer b = new Integer(10);
        System.out.println(a.equals(b));
}

结果:


代码3:

public class BiJiaoTest {
    public static void main(String[] args) {
        Value a = new Value();
        Value b = new Value();
        a.i = b.i = 10;
        System.out.println(a == b);
    }
}
class Value{
    int i;
}

结果:


代码4:

public class BiJiaoTest {
    public static void main(String[] args) {
        Value a = new Value();
        Value b = new Value();
        a.i = b.i = 10;
        System.out.println(a.equals(b));
    }
}
class Value{
    int i;
}

结果:


总结:

== 是一个关系运算符,使用与所有内建的数据类型,同样也适用于所有对象,检查两个对象是否相等。

代码1中,a == b 返回true。因为a 、b 都是基本数据类型,基本数据类型都是存在栈里面的,当jvm执行int a = 10时,首先会创建 int a 的引用,然后去栈里面找是不是有一个数据为10,如果有就将a 指向这个地址,如果没有就创建一个地址。int b = 10也是相同的道理。所以当a 和 b 值相同的时候,地址也是相同的。

代码1中,c == d 返回true。Integer c = 10 是int 类型的自动装箱操作,调用了Integer的valueOf()方法,当c >= -128 并且c <=127时,用了常量池技术,所以c 和 d的地址也是相同的。valueOf源码如下:

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


private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
}

代码1中,e == f 返回false。因为e  和 f 大于127 ,进行了new 的操作,e 和 f 的地址是不同的。

equals()方法是Object类中的一个方法,方法中也是用 “==” 来实现的。下面是Object类中equals()方法的源码:

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

所以equals()方法比较的也是两个对象的地址。但是为什么代码2中用equals()方法结果却是true呢?因为Integer类中重写了equals()方法,方法中把Integer进行拆箱操作,对比的是基本数据类型。源码如下:

private final int value;

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
}

代码4中Value对象并没有重写父类Object的equals()方法,所以调用的其实是Object类中的equals()方法,其实也是用==比较的 所以结果为false;

  • ==永远是用来比较内存中的地址的,基本类型感觉上是在比较内容,实际上还是在比较地址!
  • 大多数JAVA类库都重了写equals()方法,所以它实际比较的是对象的内容,而非他们的地址。
  • 但是在我们自定义的对象中,如果我们没有重写equals()方法,那么他们比较的就是地址而非内容。
  • 重写equals()方法应注意以下几点:
  1. 自反性:对任意引用值x,x.equals(x)的返回值一定为true;
  2. 对称性:对于任意引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
  3. 传递性:如果x.equals(y) = true,y.equals(z) = true,则x.equals(z) = true;
  4. 一致性:如果参与比较的对象没有任何改变,则对象比较的结果也不应该有任何改变。
  5. 非空性:任何非空的引用值x,x.equals(null)的返回值一定为false。
     

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值