오늘 AJN에서 Agile Java 스터디를 하던 중 예전에 작성했던 Auto (un)boxing은 -128~127 (4) 이 글을 살펴보게 되었습니다.

저 글을 작성할 당시 저 내용을 저도 제대로 이해하고 있지 않았었는데 이번에는 좀 더 이해가 되면서 오히려 의문스러운 점이 발생했습니다.(말이 좀 이상하지만;;)

간략하게 요약하면 다음과 같습니다.

        checkIntegerSame(127, 127); // same

        checkIntegerSame(128, 128); // Not same

        checkIntegerEquals(128, 128); // equals

        checkIntegerSame(-128, -128); // same

        checkIntegerSame(-129, -129); // Not same

        checkIntegerEquals(-129, -129); // equals

위와 같은 호출이 있을 때 다음과 같은 결과가 나옵니다.

ii = 127, jj = 127 ==> jj is same ii.
ii = 128, jj = 128 ==> jj is NOT same ii!!
ii = 128, jj = 128 ==> jj is equals ii.
ii = -128, jj = -128 ==> jj is same ii.
ii = -129, jj = -129 ==> jj is NOT same ii!!
ii = -129, jj = -129 ==> jj is equals ii.

checkIntegerSame 메소드와 checkIntegerEquals 메소드는 다음과 같습니다.

    private static void checkIntegerSame(Integer ii, Integer jj) {
        if (ii == jj) {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is same ii.");
        }
        else {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is NOT same ii!!");
        }
    }

    private static void checkIntegerEquals(Integer ii, Integer jj) {
        if (ii.equals(jj)) {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is equals ii.");
        }
        else {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is NOT equals ii!!");
        }
    }

이상하지 않으신가요..

맨 위에서 호출한 메소드들에 넘겨준 값들은 모두 primitive 타입 입니다. 그 값들이 checkIntegerSame 이 메소드의 인자로 넘어갈 때 Autobixing이 일어납니다.(Java 5 이상에서) 그래서 각각의 메소드에서 == 비교를 하는데...

이상한 부분은 제일 첫 번째 메소드 호출 checkIntegerSame(127, 127); 의 결과가 ii = 127, jj = 127 ==> jj is same ii. 이렇게 나왔다는 것입니다. 어떻게 같게 나올 수 가 있을까요?

        if(new Integer(127) == new Integer(127)){
            System.out.println("오.. 말도 안돼...");
        }

위의 코드를 실행해서 "오.. 말도 안돼.."가 출력되는 거랑 같은 상황인 겁니다.(물론 위의 코드는 false가 되기 때문에 아무것도 출력하지 않습니다. 테스트 해 봤습니다.)

그렇다면 내릴 수 있는 가설은 하나....(지금 제 머릿속에서는 이것 밖에 생각이 나지 않습니다.)

Autoboxing을 할 때 -128~127의 정수 값들은 Immutable한 Integer 객체로 다뤄지고 그 범위를 벗어나는 객체들은 매번 새로운 객체로 만들어 진다.

무슨 말인고 하니.. 예를 들어, String s1 = "hi"; String s2 = "hi"; 이 때 다음과 같이 비교를 하면

if(s1 == s2) {
 sysout("당연하지");
}

"당연하지"를 출력합니다. String 객체를 ""를 사용하여 만들 때 Immutable하게 만들기 때문입니다. 그러나 new 키워드를 사용하면 그렇치 않고 매번 객체를 생성하게 되죠. 이것과 마찬가지의 일이 Autoboxing에서도 일어나고 있다고 가설을 내려 봅니다.