フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

Javaで-128~127のIntegerを==で比較するとtrueになる理由

以下のサイトで解説されています。

https://programming.guide/java/boxed-values-equality.html https://stackoverflow.com/questions/3131136/integers-caching-in-java

Integer クラスでは -128〜127 の値の場合はJVM の起動時に上記の範囲の Integer オブジェクトが高速化のため生成されているようです。

    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
            VM.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() {}
    }

jdk13/Integer.java at dcd4014cd8a6f49a564cbb95387ad01a80a20bed · openjdk/jdk13 · GitHub

そして、 -128〜127 の範囲を使用する場合は、 以下のコードに記載のように生成済みのキャッシュからオブジェクトを取得するので -128〜127 範囲の Integer を == で比較すると同じになるようです。

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

jdk13/Integer.java at dcd4014cd8a6f49a564cbb95387ad01a80a20bed · openjdk/jdk13 · GitHub

ということで

/* Online Java Compiler and Editor */
public class HelloWorld{

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

        a = 128;
        b = 128;
        System.out.println(a == b);
     }
}

は以下の結果になります。

true
false

Online Java Compiler にコードを置いてます。