Java

제네릭(Generic) 타입의 형변환

작은별._. 2023. 10. 29. 14:26
728x90

이번 포스팅에서는 제네릭 타입에서는 어떤 형변환이 가능하고 불가능한지에 대해서 알아보겠습니다.


1. 제네릭타입과 원시 타입끼리의 형변환

아래의 코드처럼 제네릭타입과 원시 타입끼리는 형변환이 가능하지만 경고가 발생합니다. 


class Box<T> {}

public class Main {
    public static void main(String[] args) {
        Box box = new Box();
        Box<String> stringBox = new Box<>();
        box = (Box)stringBox; // 가능, but 경고 발생
        stringBox = (Box<String>) box; // 가능, but 경고 발생
    }
}

2. 제네릭 타입 간의 형변환  

대입된 타입이 같은 제네릭 타입끼리는 당연히 형변환이 가능합니다. 그렇다면 다른 제네릭 타입 간에는 형변환이 가능할까요? 아쉽게도 불가능합니다. 아래 코드로 확인해 보세요!


public class Main {
    public static void main(String[] args) {
        Box<Object> objectBox = new Box<>()
        Box<String> stringBox = new Box<>();  
        Box<Integer> integerBox = new Box<>();
        stringBox = (Box<Object>) objectBox; // 불가!! (objectBox에 stringBox 대입도 불가)
        stringBox = (Box<Integer>)stringBox; // 불가!! (integerBox에 stringBox 대입도 불가)
    }
}

3. 와일드카드가 사용된 제네릭 타입끼리의 형변환

와일드 카드가 사용된 제네릭 타입끼리는 조상-자손 관계(상속 관계)라면 형변환이 가능합니다.


public class Main {
    public static void main(String[] args) {
        Box<?> objectBox = new Box<>(); // 
        // 위 코드는 Box<? extends Object> objectBox = new Box<Object>();와 같은 의미
        Box<? extends String> stringBox = new Box<>();
        objectBox = (Box<? extends Object>)stringBox; 
        // 혹은 (Box<?>)stringBox;
        // 혹은 objectBox = stringBox;
        stringBox = (Box<? extends String>) objectBox;
    }
}

 

또한, 원래는 <Object> 형 변수를 <String> 형 변수로 바로 형변환하는 것이 불가하였지만, <?> 와일드카드를 사용해서 다른 타입으로 형변환이 가능하게 됩니다. 즉 아래와 같이 할 수 있습니다.


Class <Object> → Class<T>: 불가
Class<Object> → Class <?> → Class <T>: 가능, but 미확인 타입으로 인한 형변환 경고 발생 

예시 1

public class Main {
    public static void main(String[] args) {
        Box<?> objectBox = new Box<>();
        Box<String> stringBox = new Box<>();
        stringBox = (Box<String>) objectBox; // 가능
    }
}

 

 


예시 2

public class Main {
    public static void main(String[] args) {
        FoodBox<? extends Food> foodBox = null;
        FoodBox<Rice> riceFoodBox = (FoodBox<Rice>) foodBox; 
    }
}

class Box<T> {}
class FoodBox<T extends Food> extends Box<T>{}
class Food {}
class Rice extends Food{}

 

 

[참고자료]

남궁 성, [Java의 정석 3rd Edition], 도우출판, 2016

 

728x90
반응형