흥미로운 오토 박싱에 대한 자바 작은 선물

면책 조항 :이 문서는 블로거 원본입니다, 추적 에 의해-SA의 CC 4.0 저작권 계약, 복제, 원본 소스 링크이 문을 첨부 해주세요.
이 링크 : https://blog.csdn.net/weixin_45614509/article/details/102748979

이 책의 예은 "Java 가상 머신의 깊이있는 이해", 다음 코드의 결과가 실행되는 것을 생각인가?

    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 1;
        Integer c = 3;
        Integer d = 3;
        Integer e = 138;
        Integer f = 138;
        Long g = 3L;

        System.out.println(c == d);
        System.out.println(e == f);
        System.out.println(c == (a + b));
        System.out.println(c.equals(a + b));
        System.out.println(g == (a + b));
        System.out.println(g.equals(a + b));
    }

우리가 처음 ==와 객체의 동등한의 차이를 알고 있어야이 이해 == 메모리에 비교 주소 즉, 둘의 비교는 동일한 개체 수 있는지 여부, 동일합니다. 일반적 방법은 객체의 내용이 동일 비교합니다,하지만 재정이없는 경우 여전히 개체는 사실, 방법과 동일 전화를 비교하는 == 사용하는 것입니다, 방법 같습니다.

이 아래로보고 계속 알고 :

== C D의

C 및 D는, 비록 3이지만 == 비교하여, 비교 Interger C와 동일한 메모리 어드레스 D Interger 형의 등가 형태. 그래서 결과가 거짓 인 것 같아요.

== E F의
공감

C == (a + b)

로 인해 B A + 실행시 정수 확실히 두 개체가 첨가되지 않은 B, 그것은 자동 INT으로 A와 B를 푸는 것, 결과를 첨가 INT, 정수 INT 타입 3 및 타입 3 확실히 동일하지 않다. 그래서 추측은 false입니다

c.equals (a + b)

정수 값을 비교 이라기보다 메모리 어드레스보다 동일하므로 결과가 참 추측

== g의 (a + b)

마찬가지로, 잘못된 추측

g.equals (a + b)

g는 롱 타입의 유형 및 INT A + B의 비교 결과이기 때문에 확실히 거짓. 그래서 추측은 false입니다


그리고 다음과 같은 결과가 실행 :

true
false
false
false
false
false

이 잘못은, 처음 보는 추측 :

        Integer c = 3;
        Integer d = 3;
        System.out.println(c == d);

Integer c = 3;자동 포장기구 때문에 당량 Integer.valueOf(3), Integer d = 3일반적으로 이입하고, 두 가지 목적 있어야하지만 상기 비교 결과 메모리 어드레스가 동일하다고 밝혀졌다. 우리는 소스 코드에 대한보고를 주문했다 :

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

아? 도대체 IntegerCache? 결과 C는 == D 사실, 소스 코드 클릭을 살펴 이유를 이해할 수 있도록, 캐시의 이름이 사용되는 볼 수 있습니다 봐 :

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

, C 및 D가 그렇게 실제로 어디에 IntegerCache 배열 버퍼까지의 범위 내에서 데이터 바이트는 Integer.valueOf를 사용하여 각 시간에서 픽업 것, 즉 -128에서 127 사이의 정수를 사용 객체.

c.equals (A + B를)

알 소스의이보기 :

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

instanceof를 개체가 결과 A + B와 동일한 int로는 개체가 속해 있는지 여부를 확인하기 위해 소스 코드에서 먼저 수행하고, 패킹 자동으로 발생하지 않는 obj instanceof Integer상태가 직접 false를 반환 확립되지 않습니다.


실제로 한 자동 복싱과 언 박싱을 사용하지 않아야합니다

추천

출처blog.csdn.net/weixin_45614509/article/details/102748979