[자바 무료 강의] Wrapper - 코드라떼
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의Wrapper최종수정일 2022-04-02
아이콘15분

특수 목적에 의해 만들어진 Wrapper 클래스에 대해서 배우는 강의입니다.

노트 강의

Wrapper 클래스


자바에는 기본 자료형(Primitive Type)을 감싸는 Wrapper 클래스가 존재합니다.


기본 자료형에는 byte, short, int, long, float, double, boolean, char가 있습니다.


이러한 자료형은 인스턴스가 아니라, 상숫값 자체를 의미하거나 이러한 상숫값을 저장하는 기본 자료형 변수로서 사용됩니다.


이러한 기본 자료형도 특정 목적에 의해 인스턴스로 바꿔서 사용해야 하는 경우가 있습니다.

List<Object> list = new ArrayList<>();
list.add(object);

기본적으로 ArrayListlist.add(object) 메서드는 Object 인스턴스를 상속받는 인스턴스의 참조 값만 전달할 수 있습니다.


그러므로 기본 자료형은 인스턴스가 아니기 때문에 Object를 상속받을 수 없죠.


그러면 어떻게 ArrayList에 기본 자료형의 값을 저장할 수 있을까요?

Integer integer = new Integer(10);

정수형 상수를 Integer의 인스턴스 생성자로 전달하면 됩니다.


Integer 클래스는 int 자료형과 매칭되는 클래스입니다.


기본 자료형과 매칭되는 클래스는 다음과 같습니다.

// 상수 값을 인스턴스화

// byte
Byte bt = new Byte(1);

// short
Short sho = new Short(10);

// int
Integer integer = new Integer(10);

// long
Long long = new Long(10L);

// float
Float flo = new Float(10.2F);

// double
Double dou = new Double(10.2);

// boolean
Boolean bool = new Boolean(true);

// char
Character character = new Character('A');

이런 클래스들을 기본 자료형의 Wrapper 클래스라고 부릅니다.


그리고 이러한 Wrapper 클래스로 만들어진 인스턴스를 통해 ArrayList에 데이터를 저장할 수 있습니다.

// Integer로 명시
List<Integer> list = new ArrayList<>();

// list에 값 저장
list.add(new Integer(10));
list.add(new Integer(20));
list.add(new Integer(30));

반대로 Wrapper 클래스로 감싼 상수 값을 어떻게 기본 자료형으로 반환 받을 수 있을까요?

Byte bt = new Byte((byte) 0);
byte bt1 = bt.byteValue();

Short sho = new Short((short) 10);
short sho1 = sho.shortValue();

Integer integer = new Integer(10);
int integer1 = integer.intValue();

Long lo = new Long(10L);
long lo1 = lo.longValue();

Float fl = new Float(10.2F);
float fl1 = fl.floatValue();

Double dou = new Double(10.2);
double dou1 = dou.doubleValue();

Character character = new Character('A');
char character1 = character.charValue();

Boolean bool = new Boolean(true);
boolean bool1 = bool.booleanValue();

각 자료형과 관련된 xxxValue() 메서드를 호출하면 기본 자료형 값을 반환받을 수 있습니다.


Auto Boxing, Auto UnBoxing

매번 new 구문을 이용하여 값을 저장하는 것은 번거롭기도 하고 코드를 작성하는 시간도 오래 걸립니다.


그래서 Java에서는 Auto Boxing, Auto Unboxing이라는 방식이 도입되었습니다.

Integer integer = 1;

이렇게 코드를 작성해도 내부적으로 인스턴스로 변환 가능하도록 만들었습니다.


1이라는 상수는 Auto Boxing 기능을 통해 new Integer(1) 인스턴스가 자동으로 생성되고 이 인스턴스의 참조 값이 참조 자료형 변수에 저장됩니다.

물론 다른 클래스도 가능합니다.

Double dou = 1.2;

이러한 Auto Boxing 기능으로 좀 더 편하게 기본 자료형 -> 참조 자료형으로 변환이 쉬워졌습니다.

// Integer로 명시
List<Integer> list = new ArrayList<>();

// list에 값 저장
list.add(10);
list.add(20);
list.add(30);

그리고 Auto Unboxing참조 자료형 -> 기본 자료형으로 변환을 쉽게 합니다.

Integer integer = 10;

int integer1 = integer;

굳이 xxxValue() 메서드를 호출하지 않아도 변환을 쉽게 합니다.



또 하나의 예시로

public static int sum(Integer a, Integer b) {
    return a + b;
}

Integer a 매개변수와, Integer b 매개변수는 인스턴스의 참조 값을 저장할 수 있습니다.


기본적으로 인스턴스의 참조값끼리 + 연산자를 통해 더할 수 없습니다만 Auto Unboxing을 통해 Wrapper 클래스는 기본 자료형으로 변환되어 연산됩니다.


그렇기 때문에 이런 코드가 실행될 수 있습니다.

int sum = sum(1, 2);

매개변수로 1과 2 상수를 전달할 때는 Auto Boxing으로 인스턴스화되며, a + b를 실행할 때는 Auto Unboxing으로 기본 자료형으로 변환되어 + 연산을 실행합니다.

그리고 반환된 값은 기본 자료형으로 int sum 변수에 결괏값을 저장할 수 있습니다.

하지만 Integer라는 참조 자료형 변수는 null 값을 저장할 수 있으므로 이런 코드도 작성 가능하게 됩니다.

int sum = sum(1, null);

이 코드가 실행되면 어떻게 될까요?

Integer Wrapper 클래스는 내부적으로 Auto Boxing에 의해 기본 자료형으로 변환하려고 합니다. 그러나 참조 값이 null 이므로, NullPointerException이 발생합니다.

public static int sum(Integer a, Integer b) {
    if (null != a && null != b) {
        return a + b;
    } else {
        return 0;
    }
}

그러므로 원치 않는 상황을 방지하려면 null 체크를 해야 합니다.

Auto Boxing, Auto Unboxing을 정리하면

기본 자료형을 기본 자료형을 담고 있는 인스턴스로 변환하고 반대로 인스턴스를 기본 자료형으로 변환합니다.


성능의 차이

기본 자료형 -> 참조 자료형 또는 참조 자료형 -> 기본 자료형으로 변환하는 연산은 기본 자료형만 이용하는 연산보다 느립니다.

특별한 목적이 아니고서는 가급적 기본 자료형을 이용하여 산술 연산하는 것이 좋습니다.



기본 자료형 산술연산

int sum = 0;

for (int i = 0; i < 1000000; i++) {
   sum += i;
}

// 평균 6 ms

0 부터 1,000,000 까지의 수를 더한다고 가정했을 때 6 ms 정도 걸립니다. (컴퓨터 마다 다름)



참조 자료형 산술연산

int sum = 0;

// Auto Boxing, Auto Unboxing
for (int i = 0; i < 1000000; i++) {
    Integer tempI = i;
    sum += tempI;
}

// 평균 12 ms

0 부터 1,000,000 까지의 수를 더한다고 가정했을 때 변환 과정이 두 번 정도 발생하여 12 ms 정도 걸립니다. (컴퓨터마다 다름)

만약에 연산하는 수가 더 커진다면 그만큼 연산이 상대적으로 더 많아진다는 뜻으로 실행 속도가 더 차이 납니다.

그러므로 특별한 목적이 아니고서는 가급적 기본 자료형을 이용하여 산술 연산하는 것이 좋습니다.


Number

Number 클래스는 Byte, Short, Integer, Long, Float, Double 같은 Wrapper 클래스의 슈퍼 클래스입니다.

(Boolean, Character 제외)

Number 클래스는 추상 클래스이나 Auto Boxing이 적용됩니다

Number number1 = 1;

Number number2 = 2.0;

Number number 변수는 각 상수 자료형에 맞게 인스턴스가 생성되어 인스턴스의 참조값을 저장합니다.

Number number1 = 1;

Number number2 = 2.0;

// 컴파일 불가
double sum = number1 + number2;

다만 Number 클래스는 Auto Unboxing이 불가능합니다.

이유는 Number 변수에 인스턴스를 이미 저장된 후에는 참조 값만 저장하므로 Byte, Short, Integer, Long 정수인지 Float, Double 실수인지 어떤 자료형인지 알 수 없기 때문입니다.

Number number1 = 1;

Number number2 = 2.0;

// 명시적 변환이 필요
double sum = number1.doubleValue() + number2.doubleValue();

그러므로 xxxValue() 메서드를 이용한 명시적 변환이 필요합니다.


Wrapper 클래스의 또 다른 용도

Wrapper 클래스에는 기본적으로 형변환에 도움이 되는 몇 가지 메서드를 제공합니다.

앞으로 빈번히 사용하게 되므로 알아두셔야 합니다.


문자열 -> 수, 수 -> 문자열 변환**
String numberText = "1";

// 문자열 -> 정수
int number = Integer.parseInt(numberText);

// 정수 - > 문자열

String text = Integer.toString(number);

Integer.parseInt(string) 정적 메서드를 이용하여 int 정수형으로 변환할 수 있습니다.

Integer.toString(int) 정적 메서드를 이용하여 문자열로 변환할 수 있습니다.

다만 정수로 바꿀 수 없는 문자(ex: “한”, “ab”)를 변환하려고 시도할 시에는 NumberFormatException이 발생할 수 있습니다.

String numberText = "1";

// 문자열 -> 정수
byte number = Byte.parseByte(numberText);

// 정수 - > 문자열

String text = Byte.toString(number);

Byte.parseByte(string) 정적 메서드를 이용하여 byte 정수형으로 변환할 수 있습니다.

Byte.toString(int) 정적 메서드를 이용하여 문자열로 변환할 수 있습니다.

다른 Wrapper 클래스의 정적 메서드도 parseXXX(string) 메서드나, toString(xxx) 메서드를 이용하여 기본 자료형으로 변환하거나, 문자열로 변환할 수 있습니다.


Max, Min Value
byte maxByteValue = Byte.MAX_VALUE;
byte minByteValue = Byte.MIN_VALUE;

int maxIntValue = Integer.MAX_VALUE;
int minIntValue = Integer.MIN_VALUE;

각 Wrapper 클래스에는 각 자료형의 최댓값과 최솟값을 알 수 있는 정적 변수가 선언되어 있습니다.

도전자 질문
아이콘이잉여(2022-09-24 21:10 작성됨)
강의 늘 잘 보고있습니다. 선생님.
궁금한 점이 있습니다.
Byte bt = new Byte((byte) 0);
byte bt1 = bt.byteValue();

Short sho = new Short((short) 10);
short sho1 = sho.shortValue();

왜 상기의 코드에서 byte와 short 기본자료형만 Wrapper Class 인스턴스를 생성할 때 명시적 형변환? 처럼 생긴 (byte), (short) 코드가 기입되는지 궁금합니다.
아이콘하하핳(2022-03-30 16:53 작성됨)
참조 자료형 산술연산에서 질문이 있습니다.

int sum = 0;

// Auto Boxing, Auto Unboxing
for (int i = 0; i < 1000000; i++) {
    Integer tempI = i;
    sum += i;
}

// 평균 12 ms

변환과정이 두번 발생한다고 하셨는데 
int i -> Integer tempI /  sum+=i; 이 두곳에서 변환되는 것이 맞나요???
맞다면 tempI 에서 i의 변환은 이해가 잘됩니다..
tempI와 i의 변수 이름도 다르고,  i = tempI와 같은 대입과정도 없어서 어떻게 변환되는지 이해가 잘안됩니다. ㅠㅠ
아이콘코드라떼(2022-04-02 16:21 작성됨)
안녕하세요. 코드라떼입니다 :)

예제가 조금 빈약했던 것 같습니다. 
말씀하신 대로 아래의 코드가 auto boxing과 auto unboxing을 잘 설명할듯합니다.

int sum = 0;

// Auto Boxing, Auto Unboxing
for (int i = 0; i < 1000000; i++) {
    Integer tempI = i;
    sum += tempI;
}

Integer tempI = i는 Auto Boxing이 진행되며 sum += tempI는 Auto Unboxing이 진행됩니다.

감사합니다.
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io
사업자등록번호 : 824-06-01921
통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호
파일
파일파일
Root
파일

Output
root$
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의Wrapper최종수정일 2022-04-02
아이콘15분

특수 목적에 의해 만들어진 Wrapper 클래스에 대해서 배우는 강의입니다.

노트 강의

Wrapper 클래스


자바에는 기본 자료형(Primitive Type)을 감싸는 Wrapper 클래스가 존재합니다.


기본 자료형에는 byte, short, int, long, float, double, boolean, char가 있습니다.


이러한 자료형은 인스턴스가 아니라, 상숫값 자체를 의미하거나 이러한 상숫값을 저장하는 기본 자료형 변수로서 사용됩니다.


이러한 기본 자료형도 특정 목적에 의해 인스턴스로 바꿔서 사용해야 하는 경우가 있습니다.

List<Object> list = new ArrayList<>();
list.add(object);

기본적으로 ArrayListlist.add(object) 메서드는 Object 인스턴스를 상속받는 인스턴스의 참조 값만 전달할 수 있습니다.


그러므로 기본 자료형은 인스턴스가 아니기 때문에 Object를 상속받을 수 없죠.


그러면 어떻게 ArrayList에 기본 자료형의 값을 저장할 수 있을까요?

Integer integer = new Integer(10);

정수형 상수를 Integer의 인스턴스 생성자로 전달하면 됩니다.


Integer 클래스는 int 자료형과 매칭되는 클래스입니다.


기본 자료형과 매칭되는 클래스는 다음과 같습니다.

// 상수 값을 인스턴스화

// byte
Byte bt = new Byte(1);

// short
Short sho = new Short(10);

// int
Integer integer = new Integer(10);

// long
Long long = new Long(10L);

// float
Float flo = new Float(10.2F);

// double
Double dou = new Double(10.2);

// boolean
Boolean bool = new Boolean(true);

// char
Character character = new Character('A');

이런 클래스들을 기본 자료형의 Wrapper 클래스라고 부릅니다.


그리고 이러한 Wrapper 클래스로 만들어진 인스턴스를 통해 ArrayList에 데이터를 저장할 수 있습니다.

// Integer로 명시
List<Integer> list = new ArrayList<>();

// list에 값 저장
list.add(new Integer(10));
list.add(new Integer(20));
list.add(new Integer(30));

반대로 Wrapper 클래스로 감싼 상수 값을 어떻게 기본 자료형으로 반환 받을 수 있을까요?

Byte bt = new Byte((byte) 0);
byte bt1 = bt.byteValue();

Short sho = new Short((short) 10);
short sho1 = sho.shortValue();

Integer integer = new Integer(10);
int integer1 = integer.intValue();

Long lo = new Long(10L);
long lo1 = lo.longValue();

Float fl = new Float(10.2F);
float fl1 = fl.floatValue();

Double dou = new Double(10.2);
double dou1 = dou.doubleValue();

Character character = new Character('A');
char character1 = character.charValue();

Boolean bool = new Boolean(true);
boolean bool1 = bool.booleanValue();

각 자료형과 관련된 xxxValue() 메서드를 호출하면 기본 자료형 값을 반환받을 수 있습니다.


Auto Boxing, Auto UnBoxing

매번 new 구문을 이용하여 값을 저장하는 것은 번거롭기도 하고 코드를 작성하는 시간도 오래 걸립니다.


그래서 Java에서는 Auto Boxing, Auto Unboxing이라는 방식이 도입되었습니다.

Integer integer = 1;

이렇게 코드를 작성해도 내부적으로 인스턴스로 변환 가능하도록 만들었습니다.


1이라는 상수는 Auto Boxing 기능을 통해 new Integer(1) 인스턴스가 자동으로 생성되고 이 인스턴스의 참조 값이 참조 자료형 변수에 저장됩니다.

물론 다른 클래스도 가능합니다.

Double dou = 1.2;

이러한 Auto Boxing 기능으로 좀 더 편하게 기본 자료형 -> 참조 자료형으로 변환이 쉬워졌습니다.

// Integer로 명시
List<Integer> list = new ArrayList<>();

// list에 값 저장
list.add(10);
list.add(20);
list.add(30);

그리고 Auto Unboxing참조 자료형 -> 기본 자료형으로 변환을 쉽게 합니다.

Integer integer = 10;

int integer1 = integer;

굳이 xxxValue() 메서드를 호출하지 않아도 변환을 쉽게 합니다.



또 하나의 예시로

public static int sum(Integer a, Integer b) {
    return a + b;
}

Integer a 매개변수와, Integer b 매개변수는 인스턴스의 참조 값을 저장할 수 있습니다.


기본적으로 인스턴스의 참조값끼리 + 연산자를 통해 더할 수 없습니다만 Auto Unboxing을 통해 Wrapper 클래스는 기본 자료형으로 변환되어 연산됩니다.


그렇기 때문에 이런 코드가 실행될 수 있습니다.

int sum = sum(1, 2);

매개변수로 1과 2 상수를 전달할 때는 Auto Boxing으로 인스턴스화되며, a + b를 실행할 때는 Auto Unboxing으로 기본 자료형으로 변환되어 + 연산을 실행합니다.

그리고 반환된 값은 기본 자료형으로 int sum 변수에 결괏값을 저장할 수 있습니다.

하지만 Integer라는 참조 자료형 변수는 null 값을 저장할 수 있으므로 이런 코드도 작성 가능하게 됩니다.

int sum = sum(1, null);

이 코드가 실행되면 어떻게 될까요?

Integer Wrapper 클래스는 내부적으로 Auto Boxing에 의해 기본 자료형으로 변환하려고 합니다. 그러나 참조 값이 null 이므로, NullPointerException이 발생합니다.

public static int sum(Integer a, Integer b) {
    if (null != a && null != b) {
        return a + b;
    } else {
        return 0;
    }
}

그러므로 원치 않는 상황을 방지하려면 null 체크를 해야 합니다.

Auto Boxing, Auto Unboxing을 정리하면

기본 자료형을 기본 자료형을 담고 있는 인스턴스로 변환하고 반대로 인스턴스를 기본 자료형으로 변환합니다.


성능의 차이

기본 자료형 -> 참조 자료형 또는 참조 자료형 -> 기본 자료형으로 변환하는 연산은 기본 자료형만 이용하는 연산보다 느립니다.

특별한 목적이 아니고서는 가급적 기본 자료형을 이용하여 산술 연산하는 것이 좋습니다.



기본 자료형 산술연산

int sum = 0;

for (int i = 0; i < 1000000; i++) {
   sum += i;
}

// 평균 6 ms

0 부터 1,000,000 까지의 수를 더한다고 가정했을 때 6 ms 정도 걸립니다. (컴퓨터 마다 다름)



참조 자료형 산술연산

int sum = 0;

// Auto Boxing, Auto Unboxing
for (int i = 0; i < 1000000; i++) {
    Integer tempI = i;
    sum += tempI;
}

// 평균 12 ms

0 부터 1,000,000 까지의 수를 더한다고 가정했을 때 변환 과정이 두 번 정도 발생하여 12 ms 정도 걸립니다. (컴퓨터마다 다름)

만약에 연산하는 수가 더 커진다면 그만큼 연산이 상대적으로 더 많아진다는 뜻으로 실행 속도가 더 차이 납니다.

그러므로 특별한 목적이 아니고서는 가급적 기본 자료형을 이용하여 산술 연산하는 것이 좋습니다.


Number

Number 클래스는 Byte, Short, Integer, Long, Float, Double 같은 Wrapper 클래스의 슈퍼 클래스입니다.

(Boolean, Character 제외)

Number 클래스는 추상 클래스이나 Auto Boxing이 적용됩니다

Number number1 = 1;

Number number2 = 2.0;

Number number 변수는 각 상수 자료형에 맞게 인스턴스가 생성되어 인스턴스의 참조값을 저장합니다.

Number number1 = 1;

Number number2 = 2.0;

// 컴파일 불가
double sum = number1 + number2;

다만 Number 클래스는 Auto Unboxing이 불가능합니다.

이유는 Number 변수에 인스턴스를 이미 저장된 후에는 참조 값만 저장하므로 Byte, Short, Integer, Long 정수인지 Float, Double 실수인지 어떤 자료형인지 알 수 없기 때문입니다.

Number number1 = 1;

Number number2 = 2.0;

// 명시적 변환이 필요
double sum = number1.doubleValue() + number2.doubleValue();

그러므로 xxxValue() 메서드를 이용한 명시적 변환이 필요합니다.


Wrapper 클래스의 또 다른 용도

Wrapper 클래스에는 기본적으로 형변환에 도움이 되는 몇 가지 메서드를 제공합니다.

앞으로 빈번히 사용하게 되므로 알아두셔야 합니다.


문자열 -> 수, 수 -> 문자열 변환**
String numberText = "1";

// 문자열 -> 정수
int number = Integer.parseInt(numberText);

// 정수 - > 문자열

String text = Integer.toString(number);

Integer.parseInt(string) 정적 메서드를 이용하여 int 정수형으로 변환할 수 있습니다.

Integer.toString(int) 정적 메서드를 이용하여 문자열로 변환할 수 있습니다.

다만 정수로 바꿀 수 없는 문자(ex: “한”, “ab”)를 변환하려고 시도할 시에는 NumberFormatException이 발생할 수 있습니다.

String numberText = "1";

// 문자열 -> 정수
byte number = Byte.parseByte(numberText);

// 정수 - > 문자열

String text = Byte.toString(number);

Byte.parseByte(string) 정적 메서드를 이용하여 byte 정수형으로 변환할 수 있습니다.

Byte.toString(int) 정적 메서드를 이용하여 문자열로 변환할 수 있습니다.

다른 Wrapper 클래스의 정적 메서드도 parseXXX(string) 메서드나, toString(xxx) 메서드를 이용하여 기본 자료형으로 변환하거나, 문자열로 변환할 수 있습니다.


Max, Min Value
byte maxByteValue = Byte.MAX_VALUE;
byte minByteValue = Byte.MIN_VALUE;

int maxIntValue = Integer.MAX_VALUE;
int minIntValue = Integer.MIN_VALUE;

각 Wrapper 클래스에는 각 자료형의 최댓값과 최솟값을 알 수 있는 정적 변수가 선언되어 있습니다.

도전자 질문
아이콘이잉여(2022-09-24 21:10 작성됨)
강의 늘 잘 보고있습니다. 선생님.
궁금한 점이 있습니다.
Byte bt = new Byte((byte) 0);
byte bt1 = bt.byteValue();

Short sho = new Short((short) 10);
short sho1 = sho.shortValue();

왜 상기의 코드에서 byte와 short 기본자료형만 Wrapper Class 인스턴스를 생성할 때 명시적 형변환? 처럼 생긴 (byte), (short) 코드가 기입되는지 궁금합니다.
아이콘하하핳(2022-03-30 16:53 작성됨)
참조 자료형 산술연산에서 질문이 있습니다.

int sum = 0;

// Auto Boxing, Auto Unboxing
for (int i = 0; i < 1000000; i++) {
    Integer tempI = i;
    sum += i;
}

// 평균 12 ms

변환과정이 두번 발생한다고 하셨는데 
int i -> Integer tempI /  sum+=i; 이 두곳에서 변환되는 것이 맞나요???
맞다면 tempI 에서 i의 변환은 이해가 잘됩니다..
tempI와 i의 변수 이름도 다르고,  i = tempI와 같은 대입과정도 없어서 어떻게 변환되는지 이해가 잘안됩니다. ㅠㅠ
아이콘코드라떼(2022-04-02 16:21 작성됨)
안녕하세요. 코드라떼입니다 :)

예제가 조금 빈약했던 것 같습니다. 
말씀하신 대로 아래의 코드가 auto boxing과 auto unboxing을 잘 설명할듯합니다.

int sum = 0;

// Auto Boxing, Auto Unboxing
for (int i = 0; i < 1000000; i++) {
    Integer tempI = i;
    sum += tempI;
}

Integer tempI = i는 Auto Boxing이 진행되며 sum += tempI는 Auto Unboxing이 진행됩니다.

감사합니다.
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io|운영시간 09:00 - 18:00(평일)
사업자등록번호 : 824-06-01921|통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호(경기창조혁신센터)
파일
파일파일
Root
파일

Output
root$