코린이의 소소한 공부노트

지네릭 타입의 형변환과 제거 본문

Java

지네릭 타입의 형변환과 제거

무지맘 2022. 11. 14. 23:47

[지네릭 타입의 형변환]

1. 지네릭 타입과 원시 타입 간의 형변환은 바람직하지 않다.

Box box = null;
Box<Object> objBox = null;
Box<String> strBox = null;

box = (Box)objBox; // OK. 지네릭 -> 원시. 경고 발생
objBox = (Box<Object>)box; // OK. 원시 -> 지네릭. 경고 발생
box.add(new Integer(100)); // OK. box가 원시타입이기 때문에 경고만 발생함

 2. 서로 다른 지네릭 타입으로는 형변환이 되지 않는다.

objBox = (Box<Object>)strBox; // 에러. Box<String> -X-> Box<Object>
strBox = (Box<String>)objBox; // 에러. Box<Object> -X-> Box<String>

 3. 와일드카드가 사용된 지네릭 타입으로는 형변환이 가능하다.

Box<? extends Object> wBox = (Box<? extends Object>)new Box<String>; // OK
Box<? extends Object> wBox = new Box<String>; // 위 문장과 동일
Box<?> wBox = new Box<String>; // 위 문장과 동일
 
FruitBox<? extends Fruit> fbox = new FruitBox<Fruit>(); // OK
FruitBox<? extends Fruit> abox = new FruitBox<Apple>(); // OK
// 둘다 생성자 앞에 형변환 연산자 (FruitBox<? extends Fruit>)가 생략된 형태
 
FruitBox<Apple> abox2 = (FruitBox<Apple>)abox; // OK. 와일드카드가 들어간 미확인 타입이라 경고 발생
 
// 주의: 클래스에 상한 제한이 걸려있다면 <?>는 <상한 제한>과 같다.
// 예를 들어 class Box<T extends Fruit>의 경우 아래 두 문장이 동일하다.
Box<?> b = new Box<>;
Box<?> b = new Box<Fruit>;

 

[지네릭 타입의 제거]

- 컴파일 단계에서 컴파일러는 지네릭 타입을 제거하고, 필요한 곳에 형변환을 넣는다.

- 지네릭스가 나오기 이전 버전과의 호환성(하위호환성)을 위한 결정으로, 안정성을 얻기 위한 것이다.

지네릭 타입의 경계(bound)를 제거한다.

// 제거 전				// 제거 후
class Box<T extends Fruit>{		class Box{
    void add(T t){ }			    void add(Fruit t){ } // <T extends Fruit>이었으므로 
}					} 			// Object가 아닌 Fruit으로

지네릭 타입 제거 후에 타입이 불일치하면 형변환을 추가한다.

// 제거 전				// 제거 후
T get(int i)				Fruit get(int i)
{ return list.get(i); }			{ return (Fruit)list.get(i); }

와일드카드가 포함된 경우 적절한 타입으로 형변환 추가한다.

// 제거 전							// 제거 후
static Juice makeJuice(FruitBox<? extends Fruit> box){		static Juice makeJuice(FruitBox box){
    String tmp = “”;						    String tmp = “”;
     /* Fruit의 자손임을 알기때문에 향상된 for문 사용 가능 */	    Iterator it = box.getList.iterator();
    for(Fruit f : box.getList())				    while(it.hasNext())
        tmp += f + “ ”;						        tmp += (Fruit)it.next() + “ ”;
    return new Juice(tmp);					    return new Juice(tmp);
}								}

 

'Java' 카테고리의 다른 글

애너테이션의 정의와 종류  (0) 2022.11.17
열거형(enum, enumerated type)  (0) 2022.11.17
와일드카드 ?와 지네릭 메서드  (0) 2022.11.14
지네릭 클래스의 예시와 제한  (0) 2022.11.14
지네릭스와 다형성  (0) 2022.11.09