Generic
Java 1.5부터 추가된 기능으로 다양한 타입의 객체를 다루는 변수나 클래스에 사용되는 기능이다.
컴파일 타임에 타입 오류를 잡을 수 있어 런타임 오류를 줄일 수 있습니다.
Generic 장점
- 타입 안전성 : 모든 타입에 대해 처리할 수 있지만, 실제로 사용 시, 컴파일 타임에 체크를 하므로 런타임에서는 하나의 타입만 사용하여 오류를 줄일 수 있다.
- 코드의 간결화 : 타입체크와 형변환을 생략할 수 있다.
Object
class ObjectTest {
Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
Generic 이전에 위와 같이 모든 타입을 담기 위해 Object를 통해서 값을 담아왔습니다.
Generic
class Test<T> {
T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
Test<Integer> a = new Test<>();
Test b = new Test(); // 가능, 단 기본 generic은 Object로 지정된다.
Generic연산자의 특징으로 다이아몬드 연산자(<>)를 볼 수 있다. 다이아몬드 연산자 내부에는 타입 변수가 있는데 T(Type), K(Key), V(Value), E(Element)등 관용적으로 맨 앞글자를 사용하며 어떤 글자가 와도 상관없다
Generic 제한
제네릭은 컴파일 시점에서 타입을 지정하고 제거하므로, 컴파일 이전에 타입을 알고있어야 하는 경우에서는 사용 불가하다
1. 클래스 변수에서의 사용 제한
Generic클래스에서 클래스 변수를 선언하는 것은 컴파일 타임에 결정되지 않고 사용하는 것이므로 사용하지 못한다.
2. 제네릭 배열 사용 제한
제네릭 배열 또한 선언이 불가능 합니다. 왜냐하면 배열의 new키워드가 객체를 생성하는 키워드입니다. 이때 컴파일 시점에서 타입에 대해 정확히 알고 있어야 하지만 제네릭은 컴파일을 할 때 타입을 제거하므로 선언이 불가 합니다.
Generic 와일드 카드 & 제한
Generic 와일드 카드
.java 파일에서 컴파일을 통해 제네릭 타입을 체크하고 자동 형변환을 해주기 때문에 문제점이 생긴다.
바로 메서드 오버로딩에 대한 문제이다. 따라서 메서드를 중복 정의하게 되므로 이를 해결하기 위한 해결책이 와일드 카드입니다.
Test<?> test = new Test<>();
위와 같이 ?를 통해서 모든 타입을 대체할 수 있습니다.
하지만 와일드 카드에서도 제한 하고 싶은 클래스가 있습니다.
<? extends T> // T타입 이하의 클래스 가능, T를 상속받은 클래스
<? super T> // T타입 이상의 클래스 가능, 모든 상속이나 구현
<?> // 모든 타입에 대해 가능
Generic 메서드
메서드 선언부에 제네릭 타입이 선언된 메서드를 제네릭 메서드라 한다.
제네릭 클래스에서 사용된 타입변수와, 제네릭 메서드에서 사용된 타입변수는 다른 것이다.
public static <T extends Bird> void genericMethod(Meat<T> bird) {
// 파라미터의 T를 해당 메서드 내에세 <T extends Bird>와 치환했다 생각하면 된다.
/**
* 제너릭 형변환
* 아까 언급했듯이 제네릭간 형ㄱ 변환은 와일드카드 등 편법을 사용해야한다.
* 하지만 원시타입 <-> 제네릭 은 가능
*/
Meat bird1 = bird; // Meat 원시타입과 제네릭 가능
Meat<Bird> bird2 = null; // Meat<Bird> bird2 = bird; <= T타입을 Bird타입에 넣기 때문에 불가, T가 Bird의 하위 인스턴스만 받는다 하더라도 안된다.
Meat<?> bird4 = bird; // 와일드 카드로 가능
bird1 = (Meat<Bird>) bird2; // 원시 -> 제네릭
bird2 = (Meat) bird1; // 제네릭 -> 원시
Meat<? extends Eatable> bird3 = new Meat<Bird>();
}
'JAVA > 자바스터디' 카테고리의 다른 글
[자바스터디] 쓰레드 (0) | 2023.01.28 |
---|---|
[자바스터디] Generic vs Object (0) | 2023.01.28 |
[자바 스터디] for vs foreach vs iterator (0) | 2023.01.28 |
[자바스터디] Collection - Collections (0) | 2023.01.22 |
[자바스터디] Collection - Iterator (0) | 2023.01.22 |