Java의 정석_기초편

지네릭 타입의 형 변환

DJDU 2022. 11. 8. 19:57

지네릭 타입의 형 변환

  • 지네릭 타입과 원시 타입 간의 형 변환은 바람직하지 않다.(경고 발생)
  • 와일드 카드가 사용된 지네릭 타입으로는 형변환 가능
더보기

지네릭 타입과 원시 타입 간의 형 변환은 바람직하지 않다.(경고 발생)

Box<Object> objBox = null;
Box box = (Box)objBox;           // OK. 지네릭 타입 -> 원시 타입.  경고 발생
objBox  = (Box<Object>)box;      // OK.  원시타입  -> 지네릭 타입. 경고 발생

JDK1.5부터 지네릭스가 나왔기 때문에, 이후로는 원시 타입은 쓰지 않는 것이 좋다.

예제12-3-2

class Ex12_3_2 {
    public static void main(String[] args) {
        Box b = (Box)new Box<String>();
        b.add(new Integer(100));
        Box<String> bStr = null;

        b = (Box)bStr;         // Box<String> -> Box 가능 but 경고
        bStr = (Box<String>)b; // Box -> Box<String> 가능 but 경고
    }  // main
}

지네릭끼리는 형변환이 되지 않는다.

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

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

같은 맥락으로 알아두자.

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

// 매개변수로 FruitBox<Fruit>, FruitBox<Apple>, FruitBox<Grape> 등이 가능
static Juice makeJuice(FruitBox<? extends Fruit> box) { ... }

FruitBox<? extends Fruit> box = new FruitBox<Fruit>();  // OK
FruitBox<? extends Fruit> box = new FruitBox<Apple>();  // OK

예제12-3-3

class Ex12_3_3 {
    public static void main(String[] args) {
        FruitBox<? extends Fruit> fbox = (FruitBox<? extends Fruit>)new FruitBox<Fruit>();
        // FruitBox<Apple> -> FruitBox<? extends Fruit> 가능
        FruitBox<? extends Fruit> abox = new FruitBox<Apple>();

        // FruitBox<? extends Fruit> -> FruitBox<Apple> 가능? 가능!
        FruitBox<Apple> appleBox = (FruitBox<Apple>)abox;  // OK. 경고발생 - 형변환 생략불가
    }  // main
}

 

지네릭 타입의 제거

  • 컴파일러는 지네릭 타입을 제거하고, 필요한 곳에 형변환을 넣는다.
더보기

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

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

Object 대신에 타입 변수 <T>를 썼다. 
그런데, 컴파일하면 타입 변수(T)가 다시 Object로 바뀐다. 제한된 경우에는 제한된 타입으로 바뀐다. 

'하위 호완성' 때문이다.

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

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