이 영역을 누르면 첫 페이지로 이동
Arc 블로그의 첫 페이지로 이동

Arc

페이지 맨 위로 올라가기

Arc

[Java] 아무 생각 없이 생성했는데 동일한 객체?

  • 2023.03.09 10:56
  • Language/Java
글 작성자: SeoArc

Integer.valueOf(127) == Integer.valueOf(127)은 true?

Integer.valueOf(127) == Integer.valueOf(127)은 true가 출력된다고 한다.

뭔가 이상하다. 배운대로라면 Integer는 클래스, 즉 참조 타입이기 때문에 다른 객체가 생성되어 false가 떠야 맞는 것 같은데 그렇지가 않다.

그럼 다른 객체로 생성이 안된다는 얘기일까? 한 번 살펴보자.

 

다음 코드의 실행 결과를 한 번 예상해보자.

public class IntegerCacheCheck {
    public static void main(String[] args) {
        System.out.println(Integer.valueOf(128) == Integer.valueOf(128));
        System.out.println(Integer.valueOf(127) == Integer.valueOf(127));
    }
}

 

 

위 코드는 다음과 같은 결과가 출력된다.

false
true

128은 false가 출력되고 127은 true가 출력된다. 같은 Integer형인데 왜 이렇게 서로 다른 결과가 출력되는 것일까

 

Integer.valueOf()

위 결과의 이유를 알기 위해선 Integer 내부의 valueOf(int) 메서드를 이해해야한다.

 

먼저 Integer 클래스의 valueOf(int) 메서드를 보면 다음과 같이 구현되어 있다.

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

여기서 IntegerCache.low는 -128, IntegerCache.high는 127이다. (이는 Integer 클래스의 내부 static 클래스인 IntegerCache에 선언되어 있다)

-128과 127 사이에 있는 수는 IntegerCache의 cache에서 꺼내오고 그 외의 범위는 새로운 객체를 생성하여 반환시킨다는 것을 확인할 수 있다.

 

IntegerCache

정확히 무슨 말 일까?

Integer는 내부에 Integer 객체를 미리 캐싱해두는 IntegerCache라는 static 클래스를 선언하고 있다.

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer[] cache;
    static Integer[] archivedCache;

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            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;

        // Load IntegerCache.archivedCache from archive, if possible
        VM.initializeFromArchive(IntegerCache.class);
        int size = (high - low) + 1;

        // Use the archived cache if it exists and is large enough
        if (archivedCache == null || size > archivedCache.length) {
            Integer[] c = new Integer[size];
            int j = low;
            for(int k = 0; k < c.length; k++)
                c[k] = new Integer(j++);
            archivedCache = c;
        }
        cache = archivedCache;
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

즉, -128과 127사이의 값은 Integer에서 미리 캐싱해두고 해당 범위의 값은 캐싱된 값을 반환시키는 것이다. 그래서 해당 범위의 값을 비교하면 같은 참조를 갖게 되므로 true가 나오는 것이다.

-128과 127사이의 값은 자주 사용되기 때문에 메모리를 절약하고자 캐싱을 해두고 있는 것이다.

이는 다른 관점에서 보면 플라이웨이트 패턴(Flyweight Pattern)이 적용된 것이라고 생각할 수 있다.

 

또, IntegerCache의 static block에서 값을 메모리에 초기화 하고 있으므로, 캐시는 클래스가 메모리로 로딩될 때 초기화된다.

캐싱은 Byte, Short, Long, Character 클래스에도 적용되어 있으며 그 범위는 다음과 같다.

  • Byte, Short, Long: -127 ~ 127
  • Integer: -128 ~ 127
  • Character: 0 ~ 127

'Language > Java' 카테고리의 다른 글

[Java] JVM  (0) 2023.03.20
[Java] "" vs new String("")  (2) 2023.03.19
[Java] abstract class vs interface  (0) 2023.01.20
[Java] stream vs for  (1) 2023.01.17
[Java] 3. Iterator  (0) 2022.08.17

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Java] JVM

    [Java] JVM

    2023.03.20
  • [Java] "" vs new String("")

    [Java] "" vs new String("")

    2023.03.19
  • [Java] abstract class vs interface

    [Java] abstract class vs interface

    2023.01.20
  • [Java] stream vs for

    [Java] stream vs for

    2023.01.17
다른 글 더 둘러보기

정보

Arc 블로그의 첫 페이지로 이동

Arc

  • Arc의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록

카테고리

  • 분류 전체보기 (106)
    • Language (28)
      • C++ (0)
      • C# (0)
      • Java (28)
    • Algorithm (47)
      • Algorithm (15)
      • Data Structure (6)
      • PS (26)
    • Computer Science (22)
      • Design Pattern (1)
      • Network (14)
      • OS (7)
    • Game (0)
      • Unity (0)
    • Backend (3)
      • Spring (1)
      • JPA (2)
    • DB (0)
      • SQL (0)
    • DevOps (2)
      • AWS (0)
      • Docker (2)
      • Jenkins (0)
      • Nginx (0)
    • Software Engineering (4)
      • OOP (4)
    • AI (0)
      • Machine Learning (0)
    • Others (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 네트워크
  • 자바
  • 그래프
  • algorithm
  • network
  • 알고리즘
  • graph
  • java

나의 외부 링크

정보

SeoArc의 Arc

Arc

SeoArc

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © SeoArc. Designed by Fraccino.

티스토리툴바