갑자기 문듯 코테하면서 자주 써왔던 int형과 Integer형의 차이가 궁금하였다.
내가 아는 int는 그냥 원시타입이고
Integer는 wrapper class라서 원시타입을 객체로 사용하는 것으로 NULL을 허용하고, 컬렉션 요소로 사용되는 정도만 알고 있었다.
그래서 구글링을 하였고 알아낸 정보는
int는 산술연산이 가능하고 Integer는 산술연산이 불가능하다.
음? 이게 무슨 말이지
Integer a = 1;
Integer b = 2;
System.out.print(a+b);
결과: 3
결과 3으로 잘 나오는 데 산술연산이 불가능하다고??
근데 여기서 한 가지 의문점은
클래스면 대입연산자가 불가능하므로 Integer a = new Integer(1); 으로 선언해야 되는 것이 아닌가?
이것에 대한 해답은
자바 컴파일러가 자동으로 Autoboxing과 UnBoxing을 해준다고 한다.
즉 컴파일을 하면 위의 코드는 자동으로 아래와 같이 변경된다.
Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(2);
System.out.print(a.intValue() + b.intValue());
진짜 이렇게 되는 지는 디버깅하면 알 수 있다.
Integer 자체로는 산술연산이 불가능하지만 컴파일러에 의해 자동으로 산술연산이 된 것처럼 보인 것이었다.
그렇다면 얄팍한 지식이지만 valueOf()메소드에 대해서 알아보자.
매개변수 i 값 범위가 low~high라면 IntegerCache배열에 저장된 값을 리턴하고
범위를 벗어나면 새로운 메모리를 할당해주고 있다.
IntegerCache는 Integer클래스의 내부클래스이며 초기화 과정에서 위 코드와 같이 배열에 -128~127을 할당해주고 있다.
정수형 값 범위가 -128~127이면 기존에 초기화된 값을 넘겨주고 범위를 벗어나면 새로운 객체를 할당해주고 있다는 것인데 직접 확인해보자.
Integer a = 127;
Integer b = 127;
System.out.println(a == b);
결과: true
범위에 만족했으므로 동일성에서 같은 객체로 인식한다.
만약 캐싱되는 정수형 범위를 벗어난다면?
Integer a = 128;
Integer b = 128;
System.out.println(a == b);
결과: false
동일성에서 다른 객체로 인식하고 있다.
https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
좋은 글 감사합니다