자바 기초 자동 포장
1. 포장 이란 무엇 입 니까?무엇이 상 자 를 뜯 는 것 입 니까?
자바 는 모든 기본 데이터 형식 에 대응 하 는 포장 기 유형 을 제공 합 니 다.
자바 SE5 이전에 수치 가 10 인 Integer 대상 을 만 들 려 면 이렇게 해 야 합 니 다.
Integer i = new Integer(10);
자바 SE5 부터 자동 포장 기능 을 제공 합 니 다. 수치 가 10 인 Integer 대상 을 만 들 려 면 이렇게 하면 됩 니 다.
Integer i = 10;
이 과정 에서 수치 에 따라 해당 하 는 Integer 대상 을 자동 으로 만 듭 니 다. 이것 이 바로 포장 입 니 다.
그럼 상 자 를 뜯 는 게 뭐 죠?말 그대로 포장 기 유형 을 기본 데이터 형식 으로 자동 으로 바 꾸 는 것 입 니 다.
Integer i = 10; //
int n = i; //
간단하게 말 하면
포장 은 기본 데이터 형식 을 포장 기 형식 으로 자동 으로 바 꾸 는 것 이다.
상 자 를 뜯 는 것 은 자동 으로 포장 기 유형 을 기본 데이터 형식 으로 바 꾸 는 것 이다.
다음 표 는 기본 데이터 형식 에 대응 하 는 포장 기 형식 입 니 다.
기본 데이터
포장 기 종류
int (4 바이트)
Integer
byte (1 바이트)
Byte
short (2 바이트)
Short
long (8 바이트)
Long
float (4 바이트)
Float
double (8 바이트)
Double
char (2 바이트)
Character
boolean (미 정)
Boolean
2. 포장 과 개봉 은 어떻게 이 루어 집 니까?
우 리 는 Interger 류 를 예 로 들 어 다음 코드 를 보 겠 습 니 다.
public class Main {
public static void main(String[] args) {
Integer i = 10;
int n = i;
}
}
class 파일 을 역 컴 파일 한 후 다음 과 같은 내용 을 얻 을 수 있 습 니 다.
public class Main
{
public static void main(String[] args)
{
Integer i = Integer.valueOf(10);
int n = i.intValue();
}
}
역 컴 파일 된 바이트 코드 내용 을 통 해 알 수 있 듯 이 포장 할 때 Integer 의 value Of (int) 방법 을 자동 으로 호출 합 니 다.상 자 를 뜯 을 때 자동 으로 호출 되 는 것 은 Integer 의 intValue 방법 입 니 다.
다른 것 도 비슷 하 다. 예 를 들 어 Double, Character 등 이다.
따라서 포장 과 해체 의 실현 과정 을 한 마디 로 정리 할 수 있다.
포장 과정 은 포장 기의 value Of 방법 을 호출 하여 이 루어 진 것 이 고, 포장 기 를 호출 하 는 xxxValue 방법 을 통 해 이 루어 진 것 이다.(xxx 는 대응 하 는 기본 데이터 형식 을 대표 합 니 다).
3. 면접 관련 질문
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
false 를 출력 한다 거나 true 를 출력 한다 고 말 하 는 친구 도 있 을 것 이다.하지만 사실상 출력 결 과 는:
true
false
왜 이런 결과 가 나 왔 을 까?
출력 결과 i1 과 i2 는 같은 대상 을 가리 키 고 i3 와 i4 는 다른 대상 을 가리킨다.
이 때 원본 코드 만 보면 알 수 있 습 니 다. 아래 코드 는 Integer 의 value Of 방법의 구체 적 인 실현 입 니 다.
/**
* 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);
}
그 중에서 Integer Cache 류 의 실현 은 다음 과 같다.
/**
* 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=} 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() {}
}
이 2 단 코드 를 통 해 알 수 있 듯 이 value Of 방법 으로 Integer 대상 을 만 들 때 수치 가 [- 128, 127] 사이 에 있 으 면 Integer Cache. cache 에 존재 하 는 대상 을 가리 키 는 인용 을 되 돌려 줍 니 다.그렇지 않 으 면 새로운 Integer 대상 을 만 듭 니 다.
자바 언어 사양, 3 판 은 다음 과 같이 적 혀 있 습 니 다:
If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
메모 리 를 절약 하기 위해 다음 포장 대상 의 두 인 스 턴 스 에 대해 기본 값 이 같 을 때 그들 은 항상 =:
Boolean:( )
Byte:( )
Character: (\u0000 - \u007f)(<= 127 )
Short:(-128 — 127 )
Long:(-128 — 127 )
Float:( )
마찬가지 로 쓰레기 수 거 기 는:
Integer i = 100;
i = null;//will not make any object available for GC at all.
이 코드 는 쓰레기 회수 기의 조건 에 부합 되 는 대상 이 없습니다. 이 i 는 null 이 부여 되 었 지만, 이전에 가리 키 는 것 은 cache 중의 Integer 대상 이 고, cache 는 null 이 부여 되 지 않 았 기 때문에 Integer (100) 라 는 대상 은 여전히 존재 합 니 다.
만약 에 i 가 127 보다 크 거나 - 128 보다 작 으 면 그 대상 이 가리 키 는 대상 은 쓰레기 회수 조건 에 부합 할 것 이다.
Integer i = 10000;
i = null;//will make the newly created Integer object available for GC.
Oracle / Sun JDK 6 을 사용 하고 server 모드 에서 - XX: AutoBoxCacheMax = NNN 인 자 를 사용 하면 Integer 의 자동 캐 시 구간 을 [- 128, NNN] 으로 설정 할 수 있 습 니 다.구간 의 하 계 를 - 128 에 고정 시 키 면 설정 할 수 없습니다.
client 모드 에서 이 매개 변 수 는 잘못 되 었 습 니 다.이 매개 변 수 는 server 모드 에 만 있 습 니 다. c2 에 있 습 니 다.globals. hpp 에서 기본 값 은 128 입 니 다.그러나 이 기본 값 은 기본 조건 에서 작 동 하지 않 습 니 다. 수 동 으로 값 을 설정 하거나 - XX: + AggressiveOpts 인 자 를 켜 야 작 동 합 니 다.
- XX: + AggressiveOpts 시작 인 자 를 설정 하면 AutoBoxCacheMax 의 기본 값 이 20000 으로 변경 되 고 유효 합 니 다.
arguments. cpp 참조:
// Aggressive optimization flags -XX:+AggressiveOpts
void Arguments::set_aggressive_opts_flags() {
#ifdef COMPILER2
if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
if (FLAG_IS_DEFAULT(EliminateAutoBox)) {
FLAG_SET_DEFAULT(EliminateAutoBox, true);
}
if (FLAG_IS_DEFAULT(AutoBoxCacheMax)) {
FLAG_SET_DEFAULT(AutoBoxCacheMax, 20000);
}
// Feed the cache size setting into the JDK
char buffer[1024];
sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
add_property(buffer);
}
// ...
#endif
}
테스트 코드:
// run with:
// java -server -XX:AutoBoxCacheMax=1000 TestAutoBoxCache
public class TestAutoBoxCache {
public static void main(String[] args) {
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b);
Integer c = 1001;
Integer d = 1001;
System.out.println(c == d);
Integer e = 20000;
Integer f = 20000;
System.out.println(e == f);
}
}
명령 행 에서 테스트:
$ javac TestAutoBoxCache.java
$ java TestAutoBoxCache
false
false
false
$ java -server TestAutoBoxCache
false
false
false
$ java -Djava.lang.Integer.IntegerCache.high=1000 TestAutoBoxCache
true
false
false
$ java -server -Djava.lang.Integer.IntegerCache.high=1000 TestAutoBoxCache
true
false
false
$ java -Djava.lang.Integer.IntegerCache.high=1001 TestAutoBoxCache
true
true
false
$ java -server -Djava.lang.Integer.IntegerCache.high=1001 TestAutoBoxCache
true
true
false
$ java -XX:AutoBoxCacheMax=1000 TestAutoBoxCache
Unrecognized VM option 'AutoBoxCacheMax=1000'
Could not create the Java virtual machine.
$ java -server -XX:AutoBoxCacheMax=1000 TestAutoBoxCache
true
false
false
$ java -server -XX:AutoBoxCacheMax=1001 TestAutoBoxCache
true
true
false
$ java -server -XX:+AggressiveOpts TestAutoBoxCache
true
true
true
중간 신문 Unrecognized VM option 'AutoBoxCacheMax = 1000' 오 류 는 이 매개 변 수 는 HotSpot Server VM 에서 만 사용 할 수 있 고 HotSpot Client VM 에 서 는 지원 되 지 않 기 때 문 입 니 다.
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
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));
System.out.println(g.equals(a+h));
}
}
실행 결과:
true
false
true
true
true
false
true
이 안에서 주의해 야 할 것 은 '=' 연산 자의 두 조작 수 는 모두 포장 기 유형의 인용 이 고 같은 대상 을 가리 키 는 지 비교 하 는 것 입 니 다. 그 중에서 하나의 조작 수가 표현 식 (즉 산술 연산 포함) 이 라면 수치 (즉, 자동 으로 상 자 를 뜯 는 과정) 를 비교 합 니 다.
또한 포장 기 유형 에 대해 equals 방법 은 유형 전환 을 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.