제네릭
제네릭이 필요한 이유
public class IntegerBox {
private Integer value;
public void set(Integer value) {
this.value = value;
}
public Integer get() {
return value;
}
}
public class StringBox {
private String value;
public void set(String object) {
this.value = object;
}
public String get() {
return value;
}
}
단순히 set, get 하는 로직인데 타입이 달라서 중복으로 만들어야 한다.
public class ObjectBox {
private Object value;
public void set(Object object) {
this.value = object;
}
public Object get() {
return value;
}
}
public class BoxMain2 {
public static void main(String[] args) {
ObjectBox integerBox = new ObjectBox();
integerBox.set(10);
Integer integer = (Integer) integerBox.get(); // Object -> Integer 캐스팅
System.out.println("integer = " + integer);
ObjectBox stringBox = new ObjectBox();
stringBox.set("hello");
String str = (String) stringBox.get(); // Object -> String 캐스팅
System.out.println("str = " + str);
// 잘못된 타입의 인수 전달시
integerBox.set("문자100");
Integer result = (Integer) integerBox.get(); // String -> Integer 캐스팅 예외
System.out.println("result = " + result);
}
}
중복을 해결하기 위해 Object로 선언한다.
하지만 get() 할 때마다 직접 다운 캐스팅을 해줘야 하고 잘못 캐스팅 했을 때 예외가 발생한다.
원하는 타입을 정확하게 지정해서 받을 수 없다.
코드 재사용성은 높아졌으나 타입 안정성이 떨어진다.
제네릭 적용
public class GenericBox<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
public class BoxMain3 {
public static void main(String[] args) {
GenericBox<Integer> integerBox = new GenericBox<Integer>(); // 생성 시점에 T의 타입 결정
integerBox.set(10);
// integerBox.set("문자100"); // Integer 타입만 허용, 컴파일 오류
Integer integer = integerBox.get(); // Integer 타입 반환 (캐스팅 X)
System.out.println("integer = " + integer);
GenericBox<String> stringBox = new GenericBox<String>();
stringBox.set("hello"); // String 타입만 허용
String str = stringBox.get(); // String 타입만 반환
System.out.println("str = " + str);
GenericBox<Double> doubleBox = new GenericBox<Double>();
doubleBox.set(10.5);
Double doubleValue = doubleBox.get();
System.out.println("doubleValue = " + doubleValue);
// 타입 추론: 생성하는 제네릭 타입 생략 가능
GenericBox<Integer> integerBox2 = new GenericBox<>();
}
}
생성 시점에 원하는 타입을 결정할 수 있다.
제네릭 타입
클래스, 인터페이스를 정의할 때 타입 매개변수를 사용하는 것
GenericBox<T>
를 제네릭 타입이라고 한다.
타입 매개변수
제네릭 타입이나 메서드에서 사용되는 변수. 실제 타입으로 대체된다.
T
를 타입 매개변수라고 한다.
타입 인자
제네릭 타입을 사용할 떄 제공되는 실제 타입
GenericBox<Integer>
의Integer
를 일컫는다.
명명 관례
E
Element
K
Key
N
Number
T
Type
V
Value
S,U,V etc.
2nd, 3rd, 4th types
기타
class Data<K, V> {
}
여러 타입 매개변수를 선언할 수 있다.
타입 인자로 기본형은 상요할 수 없다. 대신 래퍼 클래스를 사용한다.
raw 타입
GenericBox integerBox = new GenericBox();
< >
로 사용 시점에 타입을 지정하지 않는 것Object로 사용된다.
낮은 자바 버전과 호환하기 위해 어쩔 수 없이 만들어졌다. 사용하지 않는 게 좋다.
Last updated
Was this helpful?