专业编程基础技术教程

网站首页 > 基础教程 正文

equals与==的区别你真知道吗

ccvgpt 2024-08-06 12:36:08 基础教程 13 ℃

先看这段代码,思考一下返回结果

Integer a1 = Integer.valueOf(1);
Integer b1 = Integer.valueOf(1);
System.out.println(a1 == b1);
System.out.println(a1.equals(b1));

Integer a2 = Integer.valueOf(128);
Integer b2 = Integer.valueOf(128);
System.out.println(a2 == b2);
System.out.println(a2.equals(b2));

实际返回 true,true,false,true,是和你的结果一样吗?

equals与==的区别你真知道吗

如果不一样建议你仔细看下下面的分析。

先看下Integer的源码对equals方法的重写

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

清楚看到,Integer中equals就是比较值是否相等,因此第2个和第4个都返回true

那第一个为什么返回true,第三个为什么返回false?

我们接着分析,再看下Integer中的valueOf方法

/**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    @IntrinsicCandidate
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

里面有用到IntegerCache,IntegerCache是个什么东东?再看下IntegerCache源码

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

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

        // Load IntegerCache.archivedCache from archive, if possible
        CDS.initializeFromArchive(IntegerCache.class);
        int size = (high - low) + 1;

        // Use the archived cache if it exists and is large enough
        if (archivedCache == null || size > archivedCache.length) {
            Integer[] c = new Integer[size];
            int j = low;
            for(int i = 0; i < c.length; i++) {
                c[i] = new Integer(j++);
            }
            archivedCache = c;
        }
        cache = archivedCache;
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

哦,原来IntegerCache是Integer对象的缓存池,从jdk1.5开始,Integer内部定义了一个Integer常量池,当创建Integer对象时,不使用new Integer(int i)语句,大小在-128~127之间,对象存放在Integer常量池中。Integer.valueOf(128),刚好超过了常量池,因此新建了一个新的Integer对象。所以第三个结果返回false。

另外从jdk1.6开始,IntegerCache的上限是可以通过jvm启动参数设置的。java.lang.Integer.IntegerCache.high。

总结一下

== 和 equals() 是 Java 中用于比较对象或值是否相等的操作符和方法,但它们在使用和比较的对象类型上有明显的区别。

== 是一个比较操作符,用于比较两个基本数据类型或两个对象的引用是否相等。对于基本数据类型(如 int、float、char 等),== 比较的是值;对于对象引用类型,== 比较的是两个引用是否指向内存中的同一个对象。

equals() 是一个方法,属于java.lang.Object类,所有Java类都继承自这个类,因此所有对象都可以调用 equals() 方法。默认情况下,equals() 方法的行为与 == 相同,即比较两个对象的引用是否相等。但是,许多类(如 String、Integer 等)都重写了 equals() 方法,使其可以比较对象的值而非引用。

最近发表
标签列表