1. 소개
자동박싱과 자동언박싱이란? 정수 캐시란 무엇입니까? 그들 사이의 관계는 무엇입니까?
먼저 질문 하나를 살펴보겠습니다.
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
Integer c = 1;
Integer d = 1;
System.out.println(c==d);
Integer e = 128;
Integer f = 128;
System.out.println(e==f);
먼저 답하고 나중에 답을 보세요.
답은 거짓 참 거짓입니다 맞나요?
이제 한 작품이 나왔으니 지식 포인트를 함께 나열해 볼까요
2. 패키징 클래스
자바에는 8가지 기본 데이터 유형이 있으며, 이는 세 가지 범주로 나눌 수 있습니다.
패키징 클래스는 Java의 세 가지 주요 기능인 캡슐화, 상속 및 다형성을 사용할 수 있도록 8가지 기본 데이터 유형을 클래스로 래핑합니다. 해당 관계는 다음과 같습니다.
기본 데이터 유형 |
해당 패키징 클래스 |
byte |
Byte |
short |
Short |
int |
Integer |
long | Character |
숫자 유형에 해당하는 6개의 패키징 클래스는 모두 Number 클래스에서 상속됩니다. |
3. 자동 박싱과 자동 언박싱 |
8가지 기본 데이터 유형이 8가지 패키징 클래스에 해당하는데, 데이터 변환은 어떻게 수행되나요? //基本数据类型转包装类
//1.有参构造
Integer a = new Integer(1);
//2.实际上,有参构造的参数也可以是字符串,不过要使用正确的数据,“123abc”不可能会转换为Integer类型
Integer b = new Integer("123");
//3.valueOf()
Integer c = Integer.valueOf(123);
//包装类转基本数据类型(xxxValue() float是floatValue() double是doubleValue())
int d = a.intValue();
위의 형식은 상대적으로 인식과 일치합니다. 객체를 얻으려면 new를 사용하거나 특정 메서드를 호출하면 객체의 특정 속성을 호출할 수 있습니다. |
Java 5.0 이후에는 더 이상 번거롭게 작업할 필요가 없습니다. 자동 박싱과 자동 언박싱이라는 새로운 기능이 추가되었습니다. 실제로 두 개념은 매우 이해하기 쉽습니다. | int a = 10;
Integer b = a; //自动装箱
int c = b; //自动拆箱
얼핏 보면 객체=숫자값의 형태가 인지와 맞지 않는데, 자동박싱과 자동 언박싱의 도움으로 이를 달성할 수 있습니다. 실제로 컴파일러는 여전히 valueOf() 및 xxxValue()의 도움으로 이를 구현합니다.
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
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
valueOf()는 단순히 Integer 객체를 반환하는 것이 아니라 먼저 판단을 내립니다. 입력 데이터가 특정 범위와 일치하면 특정 객체가 반환되며, 이 범위는 기본적으로 [- 128,127]입니다. 범위가 더 클 수 있습니다. 이 범위를 벗어나면 새 객체가 반환됩니다. 사용되는 IntegerCache 데이터는 Integer의 캐시입니다. |
4. 정수 캐시
수치 계산은 일상생활에서 자주 사용됩니다. 계속해서 새로운 Integer 객체를 얻으면 오버헤드가 매우 커집니다. 따라서 Java는 프로그램을 실행할 때 자동으로 정적 배열을 생성합니다. 기본적으로 이에 해당합니다. 캐시 배열 범위는 [-128,127]입니다. 데이터가 이 범위 내에 있으면 해당 개체를 캐시에서 얻을 수 있습니다. |
IntegerCache 소스 코드를 살펴보세요. | /**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
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() {}
}
IntegerCache는 Integer의 정적 내부 클래스임을 알 수 있습니다. valueOf()에 의해 호출되는 IntegerCache.cache는 배열의 크기가 범위의 최대값과 최소값에 따라 달라집니다. [-128, 127] 물론(댓글에 나와 있음) 이 범위는 JVM을 통해 수정될 수도 있습니다(이해가 안 되네요). 그런 다음 배열의 각 요소에 Integer 개체가 할당되고 캐시가 형성됩니다.
배열 캐시가 있는데, 이는 값이 [-128,127]에 있으면 valueOf() 또는 자동 박싱을 사용하여 생성된 Integer 개체를 배열에서 꺼내므로 개체가 가리키는 메모리 주소가 정확히 똑같다. new를 사용하거나 이 범위를 초과하는 경우 개체를 다시 만들어야 합니다.
물론 Integer에만 캐싱 메커니즘이 있는 것이 아니라 Byte, Short, Long 및 Character에도 모두 캐싱 메커니즘이 있습니다. Byte, Short, Integer, Long의 범위는 -128~127이고, Character의 범위는 0~127입니다.
5. 질문에 답하세요
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
Integer c = 1;
Integer d = 1;
System.out.println(c==d);
Integer e = 128;
Integer f = 128;
System.out.println(e==f);
1. new로 생성된 두 개체가 동일한 값을 가지더라도 ==를 사용하면 결과가 false로 반환됩니다.
2. 메커니즘, 두 개체는 실제로 동일하며 반환 결과는 true
3. 캐시 범위를 초과하면 실행 중에 새 개체가 생성됩니다. 두 개체가 다르면 반환 결과는 false입니다.
위 내용은 Java 자동 박싱, 자동 언박싱 및 정수 캐싱을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!