이 책의 예은 "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를 반환 확립되지 않습니다.
실제로 한 자동 복싱과 언 박싱을 사용하지 않아야합니다