이전 글에서 Primitive type 과 Reference type에 대해서 공부했다.
이번에는 오토박싱(Autoboxing)과 언박싱(Unboxing)에 대해 알아보자
- Autoboxing and Unboxing
Oracle Java Doc에서는 이렇게 말하고있다.
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.
오토박싱은 자바 컴파일러가 원시타입(primitive type)과 그들의 참조타입(object wrapper classes) 사이를 자동 변환 해주는걸 말한다.
예를들면 int 를 Integer로 , double을 Double로 변환하듯이 말이다.
만약 이 변환이 반대로 된다면, 이게 언박싱이다.
나름 길게 설명하고 있지만
단순히 얘기하자면 primitive type을 referenece type인 그들의 wrapper class로 자동 변환해주는걸 말한다는 것이다.
아래 표에서 오른쪽으로 변환이 오토박싱
왼쪽으로 변환아 언박싱이다.
Primitive type | Wrapper class |
byte | Byte |
boolean | Boolean |
char | Character |
double | Double |
float | Float |
int | Integer |
long | Long |
short | Short |
Autoboxing
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(i);
List<Integer> 는 Integer object를 가지는 List다.
근데 for문을 보면 primitive type인 int 를 대입해주어도 에러가 나지않는것을 확인할 수 있다.
자바 컴파일러가 자동으로 오토박싱을 해주기 때문에
실제로는 아래코드처럼 li 에 Integer object가 들어가게된다.
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(Integer.valueOf(i));
Unboxing
public static int sumEven(List<Integer> li) {
int sum = 0;
for (Integer i: li)
if (i % 2 == 0)
sum += i;
return sum;
}
sumEven 는
Integer object를 가지는 List인 li를 받아서 해당 값이 짝수면 sum에 더해주는 method다.
나머지를 구하는 remainder(%)나 += 연산자는 Integer object에 쓸 수 없다.
하지만 이번에도 에러는 나지 않는다.
왜냐하면 컴파일러가 언박싱을 통해 Integer object의 값을 int로 변환해주기 때문이다.
그렇기때문에 실제로는 아래처럼 동작한다.
public static int sumEven(List<Integer> li) {
int sum = 0;
for (Integer i: li)
if (i.intValue() % 2 == 0)
sum += i.intValue();
return sum;
}
마무리
이렇게보면 자바 컴파일러한테 너무 감사할따름이다.
귀찮게 추가로 코딩할 필요없이 자동으로 변환해주니 말이다.
헌데 무지성으로 오토박싱과 언박싱을 사용하면
성능 이슈, 메모리 낭비, 잠재적인 에러 등과 같은 이슈가 생길 수 있다.
오토박싱과 언박싱은 object를 자동으로 만들고 파괴하기 때문에
프로그램을 속도를 늦추거나 garbage collection 활동을 늘릴 수 있다
이전 글에서 말한것 처럼
reference type은 primitive type보다 메모리를 많이 사용하기 때문에 메모리도 낭비하게 되고
Null을 허용하는 reference type때문에
NPE(Null Pointer Exception)와 같은 예기치 못한 에러가 발생할 수도 있다.
public class Program{
static Integer i;
public static void main(String[] args) {
if (i == 1) // NPE가 발생한다.
System.out.println(i);
}
}
또한 한,두 건 정도의 연산정도라면 괜찮을지언정 대용량이 되는 순간, 속도가 확연히 달라질 것이다.
그렇기 때문에 무지성으로 작성한 반복적인 오토캐스팅이 있는지 확인하고 코딩해야 할 것 같다.
** 참조
https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
https://www.linkedin.com/advice/1/what-benefits-drawbacks-using-autoboxing-unboxing-java
'개발자의 삶 > Java' 카테고리의 다른 글
[Java] 메소드 참조(Method References)에 대하여 ( 이중콜론 :: ) (0) | 2023.06.05 |
---|---|
[Java] 람다식(Lambda Expression)과 스트림(Stream)에 대하여 - (2) (1) | 2023.06.01 |
[Java] 람다식(Lambda Expression)과 스트림(Stream)에 대하여 - (1) (0) | 2023.05.31 |
[Java] 원시 타입(Primitive type), 참조 타입(Reference type), 래퍼클래스(Wrapper Class) (0) | 2023.05.26 |
[JAVA] 람다식 (map, filter, reduce, collect) (0) | 2021.05.04 |