Wrapper Class란
기본형 타입(Primitive Type)을 객체 형태로 다룰 수 있도록 해주는 클래스
기본형 타입은 객체가 아니므로 객체 지향 프로그래밍 기능을 완전히 활용하기 어렵다.
왜 만들어 졌는지
이러한 기본형 타입을 객체로 다룰 수 있게 만들었다. 이로써
컬렉션 프레임워크, 메서드 호출 등의 객체 지향 기능을 활용할 수 있다.
유틸리티 메서드를 제공 받을 수 있다. (parseInt ...)
어떻게 사용하는지
- boolean -> Boolean
- byte -> Byte
- char -> Character
- short -> Short
- int -> Integer
- long -> Long
- float -> Float
- double -> Double
대문자로 시작하면 래퍼 클래스
// 기본형 타입 -> 래퍼 클래스 객체 (Boxing)
Integer numObject = Integer.valueOf(num); // 명시적 박싱
Integer autoBoxed = num; // 자동 박싱
// 래퍼 클래스 객체 -> 기본형 타입 (Unboxing)
int numValue = numObject.intValue(); // 명시적 언박싱
int autoUnboxed = numObject; // 자동 언박싱
언제 사용하는 지
컬렉션 프레임워크와 사용
ArrayList, HashMap과 같은 컬렉션 클래스는 객체만을 다룰 수 있다.
기본형을 사용 못하므로 래퍼클래스를 사용해야 한다.
유틸리티 메서드를 사용하고 싶을 때
String numberStr = "123";
// 문자열을 int로 변환
int number = Integer.parseInt(numberStr);
System.out.println("Parsed int: " + number);
// 문자열을 Integer 객체로 변환
Integer numberObject = Integer.valueOf(numberStr);
System.out.println("Integer object: " + numberObject);
더 알아두면 좋은 것
- 래퍼 클래스는 불변이다.
- 만들어진 객체는 바뀌지 않는다. 변경이 된다면 다른 객체를 만들어 그 곳을 가리키는 것 뿐
- Integer에 경우 클래스 로딩 시 -128~127까지의 값이 정적 초기화 블럭에 캐싱 된다.
public class IntegerCacheExample {
public static void main(String[] args) {
Integer a = Integer.valueOf(127);
Integer b = Integer.valueOf(127);
System.out.println(a == b); // true, 동일한 객체를 참조
Integer c = Integer.valueOf(128);
Integer d = Integer.valueOf(128);
System.out.println(c == d); // false, 다른 객체를 참조
}
}
a, b에 경우 미리 캐싱된 값을 가리키기에 같이 값다. 주소가 같다는 것
c, d에 경우 캐싱된 값이 없기에 새로운 객체를 만들어 준다. 그렇기에 주소가 다르다.
정적 초기화 블록 (Static Initialization Block)
정적 초기화 블록은 클래스가 로드될 때 한 번 실행되는 코드 블록입니다. Integer 클래스의 내부에서 IntegerCache 클래스를 사용하여 이 범위의 값들을 미리 캐싱
public final class Integer extends Number implements Comparable<Integer> {
private final int value;
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
h = Math.min(i, Integer.MAX_VALUE - (-low) - 1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
}
동작 방식
- 클래스 로딩 시점: 프로그램이 시작되고 Integer 클래스가 로딩될 때, IntegerCache의 정적 초기화 블록이 실행됩니다. 이 블록에서는 -128에서 127까지의 Integer 객체를 생성하여 cache 배열에 저장합니다.
- 캐싱된 객체 사용: 이후, Integer.valueOf(int i) 메서드가 호출되면, i가 -128에서 127 사이의 값인 경우, cache 배열에서 해당 값을 반환합니다. 이 범위를 벗어나는 값에 대해서는 새로운 Integer 객체를 생성합니다.
'공부일지 > Java' 카테고리의 다른 글
[JAVA] String, StringBuffer, StringBuilder (0) | 2024.07.01 |
---|---|
[JAVA] 6/21에 배운 것 (0) | 2024.06.26 |
[JAVA] 6/20 배운거 클래스 (0) | 2024.06.20 |
[JAVA] 인터페이스와 객체지향 (0) | 2024.06.19 |
[JAVA] 추상클래스와 인터페이스 (0) | 2024.06.19 |