Ch12-15~16. 지네릭 타입
0. 목차
Chapter12. 지네릭스, 열거형, 애너테이션
Ch12 - 15. 지네릭 타입의 형변환
Ch12 - 16. 지네릭 타입의 제거
Ch12 - 15. 지네릭 타입의 형변환
▶ 지네릭 타입 - 원시 타입 간의 형변환
▷ 가능 하나, 바람직 하지 않음(경고)
Box<object> objBox = null;
Box box = (Box)objBox; // 경고, 지네릭 타입 → 원시 타입
objBox = (Box<object>)box; // 경고, 원시 타입 → 지네릭 타입
▷ 예시1
Box b = new Box<String>();
b. add(new Integer(100)); // 경고
-
경고 난 이유?
String에 Integer를 넣었으니까 - 어쨌든 들어가지는 이유?
// 보이진 않지만 자동으로 형변환 쳐주고 있는 것 Box b = (Box)new Box<String>();
- 이렇게 바꾸면?
Box<String> b = new Box<String>(); // 참조 변수에 <String> 추가 b. add(new Integer(100)); // 에러
▷ 예시2
objBox = (Box<Object>)strBox; // 에러
strBox = (Box<String>)objBox; // 에러
- 에러 난 이유?
Box<Object> objBox = null; Box<String> strBox = null;
objBox = Box<Object> → Box<String> strBox = Box<String> → Box<Object>
이런 형변환은 불가
▶ 와일드 카드가 사용 된 지네릭 타입의 형변환
▷ 가능
Box<Object> objBox = (Box<Object>)new Box<String>(); // 에러, (Box<Object>)이걸로 형변환 불가능
Box<? extends Object> objBox = (Box<? extends Object>)new Box<String>() // OK, 와일드 카드로 형변환 가능
Box<? extends Object> objBox = new Box<String>() // OK, <? extends Object> 생략한 모습, 위 문장과 동일
▶ 실습
▷ 와일드 카드가 사용 된 지네릭 타입의 형변환
<Apple> → FruitBox<? extends Fruit>
FruitBox<? extends Fruit> appleBox = (FruitBox<? extends Fruit>)new FruitBox<Apple>(); // OK FruitBox<? extends Fruit> appleBox = new FruitBox<Apple>(); // OK
▷ 반대도 가능?
FruitBox<? extends Fruit> → <Apple>
FruitBox<Apple> changeBox = (FruitBox<Apple>)aBox; // 경고
Ch12 - 16. 지네릭 타입의 제거
▶ 지네릭 타입과 컴파일러
▷ 지네릭 타입은 컴파일러가 볼 때까지만 생존
▷ 컴파일러가 확인하고 나면 지네릭 타입 제거
▷ 필요한 곳에 형변환을 넣어 줌
Object → <T> → 컴파일 → <T> 제거 → Object
▶ 컴파일러가 지네릭 타입 제거하는 과정
▷ 지네릭 타입의 경계(bound)를 제거
class Box<T extends Fruit> {
void add(T t) {
...
}
}
// ↓↓↓↓컴파일 후↓↓↓↓
class Box {
void add(Fruit t) { // T 대신 Fruit 넣어줌
...
}
}
▷ 지네릭 타입 제거 후 타입 불일치하면 형변환 추가
T get(int i) {
return list.get(i); // list의 타입과 반환 타입 T 불일치
}
// ↓↓↓↓컴파일 후↓↓↓↓
Fruit get(int i) {
return (Fruit)list.get(i); // 제네릭 타입 T가 상속받는 Fruit 타입 가져와서 형변환 추가
}
▷ 와일드 카드가 포함 된 경우 적절한 타입으로 형변환 추가
static Juice makeJuice(FruitBox<? extends Fruit> box) {
String tmp = " ";
for(Fruit f : box.getList()) tmp += f + " ";
return new Juice(tmp);
}
// ↓↓↓↓컴파일 후↓↓↓↓
static Juice makeJuice(FruitBox box) {
String tmp = " ";
for(Fruit f : box.getList().iteroater();) tmp += (Fruit)it.next() + " ";
return new Juice(tmp);
}