본문 바로가기
Dev. Handbook/Java

[Java] Boxing, Unboxing, Autoboxing 그리 int, String 연산

by breezyday 2023. 1. 3.

1. Boxing, Unboxing, Wrapper Class

https://dev-handbook.tistory.com/102

 

[Java] 데이터 타입, Primitive vs Reference, Wrapper class

1. 데이터 타입(자료형) Java에는 크게 기본형 타입과, 참조형 타입이 있다. 2. 기본형 타입 (Primitive Data Types) Java의 기본형 타입은 Java에서 Pre-defined data type으로 8가지가 있다. 구분 Data Type 길이 (byte

dev-handbook.tistory.com

앞에서 데이터 타입을 살펴보면서 Wrapper Class에 대해 알아봤습니다. Wrapper ClassJava의 기본형 타입을 객체(Object)로 변환하여 다룰 수 있도록 만든 Class입니다. 

 

기본형 데이터와 Wrapper Class 간의 데이터형 변환을 Boxing, Unboxing이라고 합니다. Boxing기본형에서 Wrapper Class로(ex: int → Integer) 변환하는 것을, UnboxingWrapper Class에서 기본형으로(ex: Integer → int) 변환하는 것입니다. 

2. Boxing : new, valueOf()

Boxing은 new 연산자를 사용하거나 valueOf() 메서드를 사용합니다.

public class BoxingEx {
    public static void main(String[] args) {
        
        int     i   = 10;
        Integer wi1 = new Integer(i);     // int -> Integer
        Integer wi2 = Integer.valueOf(i); // int -> Integer
                
        String  str = "10";
        Integer wi3 = new Integer("10");    // String -> Integer
        Integer wi4 = Integer.valueOf(str); // String -> Integer
        
        double  d   = 3.14;
        Double  wd1 = new Double(d);        // double -> Double 
        Double  wd2 = Double.valueOf(d);    // double -> Double
    }
}

3. Unboxing : [data-type]Value()

unboxing은 각 Wrapper Class의 [data-type]Value() 메서드를 사용합니다.

public class UnboxingEx {
    public static void main(String[] args) {
        
        int     i   = 10;
        Integer wi1 = new Integer(i);     // int -> Integer
        int     i2  = wi1.intValue();     // Integer -> int
                
        double  d   = 3.14;
        Double  wd1 = new Double(d);      // double -> Double 
        Double  d2  = wd1.doubleValue();  // Double -> double
    }
}

4. Autoboxing, Unboxing

앞에서는 기본형 변수에 참조형 변수의 값을 대입 혹은 그 반대의 경우 valueOf(), intValue() 등의 메서드를 사용했습니다만, Java 1.5 이상에서 이 기능을 자동으로 처리(컴파일러에서 알아서 처리)하는 것을 Autoboxing unboxing이라고 합니다.

 

정확하게는 auto boxing, auto un-boxing이지만 간략하게 Autoboxing unboxing이라고도 합니다.

public class AutoBoxingUnboxingEx {
    public static void main(String[] args) {
        
        int     i   = 10;
        Integer wi1 = i;   // Auto boxing    : int -> Integer 
        int     i2  = wi1; // Auto un-boxing : Integer -> int
                
        double  d   = 3.14;
        Double  wd1 = d;   // Auto boxing    : double -> Double 
        Double  d2  = wd1; // Auto un-boxing : Double -> double
    }
}

참고로 이클립스에서 프로젝트 Properties > Java Compiler > JDK Compliance를 1.4로 변경하고 확인해보면 아래와 같이 에러가 뜨는 것을 확인할 수 있습니다.

이 경우 Java 1.4 이하에서는 명시적으로 Boxing, Unboxing을 해주면 됩니다.

// Java 1.4 Code

    int i = 1;
    Integer wi1 = new Integer(i); 
    Integer wi2;
    
    i   = wi.intValue();      // 명시적 Unboxing
    wi2 = Integer.valueOf(i); // 명시적 Boxing

5. 기본형 비교 vs Wrapper Class 비교

기본형 데이터 타입의 비교=,!= 등의 비교 연산자를 사용하면 됩니다. Wrapper Class의 비교는  equal()과 같은 메서드를 사용해야만 합니다.

 

 

Wrapper Class는 참조형 데이터 타입이므로 주소값을 저장합니다. 따라서 두 참조형을 비교 연산자를 사용하면 논리적인 오류를 발생시킵니다. 실제 데이터값이 아니라 주소값을 비교하기 때문입니다.

public class CompareWrapperEx {
    public static void main(String[] args) {
        
        int     i1   = 1;
        int     i2   = 1;
        
        Integer wi1 = new Integer(1);
        Integer wi2 = new Integer(1);
        
        if (i1 == i2)
            System.out.println("i1 == i2");
        else
            System.out.println("i1 != i2");
        
        if (wi1 == wi2) // 주소값을 비교
            System.out.println("wi1 == wi2");
        else
            System.out.println("wi1 != wi2");
        
        if (wi1.equals(wi2)) // 실제값을 비교
            System.out.println("wi1 == wi2");
        else
            System.out.println("wi1 != wi2");
    }
}

 

// 결과
i1 == i2
wi1 != wi2
wi1 == wi2

6. int, String 연산

프로그래밍을 하다 보면 int와 String을 서로 변환해야 하는 경우가 종종 발생합니다. 그리고 두 데이터 타입을 결합해서 출력해야 하는 경우도 있습니다. 이럴 때마다 데이터 타입을 명시적으로 변환하는 것은 소스 코드의 가독성이 떨어지게 됩니다. 따라서 Java에서는 두 데이터 타입을 결합하는 경우 자동으로 형변환을 처리합니다.

 

String + intint를 String으로 변환해서 String + String 연산으로 처리합니다. 그런데 이 경우 연산자의 우선순위에 따라 원하지 않는 논리적 오류가 생길 수 있습니다. 

public class StringIntOpEx {
    public static void main(String[] args) {
        
        int    a   = 12345;
        int    b   = 1;
        String str = "12345";
        
        // int형의 자릿수 계산을 위해 문자열로 변환하여 길이를 확인
        String stra = String.valueOf(a);
        System.out.println("a    Length : " + stra.length());

        System.out.println("Str  Length : " + str.length());
        System.out.println();
        
        // str을 수칙 연산에 사용하기 위해 int로 변환
        System.out.println(a + b);
        int strnum = Integer.valueOf(str);
        System.out.println(strnum + b);
        System.out.println();
        
        // 문자열 + 정수형 = 문자열
        System.out.println("a + b = " + a + b);   
        System.out.println("a + b = " + (a + b)); // ()로 우선순위 설정  
        System.out.println("str + b = "+ str + b); 
    }
}

 

// 결과
a    Length : 5
Str  Length : 5

12346
12346

a + b = 123451
a + b = 12346
str + b = 123451

 

 

 

심화학습

https://www.geeksforgeeks.org/autoboxing-unboxing-java/

https://www.geeksforgeeks.org/output-of-java-programs-autoboxing-and-unboxing/

 

 

 

 

 

댓글