int 기본 유형을 Integer 패키징 유형으로 변환하는 과정을 boxing이라고 하고, 그 반대로 변환하는 과정을 unboxing이라고 합니다.
public static void main(String[] args) { Integer a = 127, b = 127; Integer c = 128, d= 128; System.out.println(a == b); // true System.out.println(c == d); // false }
이 코드에 참과 거짓이 나타나는 이유를 모르는 사람이 있을지 모르겠습니다. 여기에서 Java boxing의 동작을 소개합니다. 우리는 질문으로 분석합니다.
public static Integer valueOf(int i) { // -128 - 127 if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
처음에 판단이 있음을 알 수 있습니다. 값 범위가 [-128,127] 사이이면 이 캐시(정수 배열)에서 가져옵니다. 범위는 바로 새로운 것입니다.
저희 비즈니스에는 정수형의 다양한 상태 및 식별 필드가 있을 수 있으므로 이러한 값은 일반적으로 0, 1, 2, 3 등이며 더 자주 나타납니다. 캐시가 없으면 자주 새로운 객체가 필요했다가 해제되므로 메모리 공간을 많이 소모하므로 캐시가 나타나므로 공간 낭비를 최적화하는 데 큰 도움이 될 수 있습니다.
여기서는 구체적인 이유를 설명하지 않겠습니다. 주로 기본적인 컴퓨터 지식에 의존합니다. 원래 코드, 역코드, 보완 코드가 무엇인지 이해한 후에요. 왜 이 범위에 속하는지 아는 것은 쉽습니다.
이 값은 시작 매개변수를 통해서도 변경될 수 있습니다.
-XX:AutoBoxCacheMax=(size)
이제 위 코드의 결과가 다른 이유를 이해해야 하며, 이에 대해 생각해 본 적이 있습니까? for 루프에서 이와 유사한 통계 데이터 작업이 발생하면 자동 박싱이 발생합니다. 다음 코드를 살펴보겠습니다.
public static void main(String[] args) { long startTime = System.currentTimeMillis(); Integer count = 0; // int count = 0; for (int i = 0; i < 5000000; i++) { count += i; } System.out.println("计算时长:" + (System.currentTimeMillis() - startTime) + " ms"); } // 执行结果: // Integer 计算时长:51 ms // int 计算时长:6 ms
그러면 실행 결과를 통해 빈번하게 발생하는 새로운 객체에 대한 자동 박싱과 메모리 할당이 시간적, 공간적으로 성능 손실을 가져온다는 것을 명확하게 알 수 있습니다.
위의 소스 코드 읽기 및 테스트 분석을 통해 우리는 일반적으로 통계를 계산하거나 메서드에 매개 변수를 입력할 때 이러한 유형 변환 문제를 피하기 위해 최선을 다해야 한다는 결론을 내릴 수 있습니다. 전체 코드의 실행 효율성을 향상시킵니다.
Unboxing에는 복잡한 로직이 없으며 값의 기본 유형을 직접 반환합니다.
사실 반드시 그런 것은 아닙니다. 아래 샘플 코드를 보면 출력 문 뒤에 출력 결과가 주석 처리되어 있습니다.
public static void main(String[] args) { // TODO 自动生成的方法存根 Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; System.out.println(c==d);//true //包装类的==在没有遇到算术运算的情况下不会自动拆箱 System.out.println(e==f);//false System.out.println(c==(a+b));//true System.out.println(c.equals(a+b));//true System.out.println(g==(a+b));//true //equals方法不会处理数据转型关系 System.out.println(g.equals(a+b));//false }
자동 Boxing 및 Unboxing이 발생하는 상황은 다음과 같습니다.
Autoboxing: 포장 유형에 따라 기본 유형이 지정됩니다. 예: Integer i1 = 1;
자동 언박싱:
포장 유형은 기본 유형에 지정됩니다. 예: int i2 = new Integer(1);
int 유형과 Integer 유형을 비교합니다. int 유형과 Integer 유형의 값이 같으면 결과는 항상 true입니다.
정수 유형에서 산술 연산이 발생합니다
그러나 위의 예에서 System.out.println(c==d); 및 System.out.println(e==f); 똑같지 않아 똑같아?
주로 Integer.valueOf() 메서드 때문입니다. Integer의 소스 코드 일부가 아래에 게시되어 있습니다.
// 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() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
IntegerCache는 Integer의 정적 내부 클래스이고 valueOf()는 패키징 방법입니다. 소스 코드에서 볼 수 있듯이 캐시는 캐시 배열입니다. valueOf() 메서드의 입력 매개 변수 i가 [-128,127] 범위에 있으면 캐시 배열의 정수 값이 반환됩니다. 정수가 생성됩니다.
이것이 System.out.println(c==d);와 System.out.println(e==f);의 출력 결과가 다른 이유입니다. c와 d는 캐시 간격에 있으므로 동일한 참조를 반환하지만 e와 f는 캐시 간격에 없으면 더 이상 동일한 참조가 아닌 새 Integer를 반환합니다.
위 내용은 Java 자동 박싱 및 언박싱 소스 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!