본문 바로가기

Java

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

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
반응형

'Java' 카테고리의 다른 글

wait()과 notify(), notifyAll()  (2) 2023.10.29
synchronized를 이용한 쓰레드의 동기화  (2) 2023.10.29
Thread 실행 제어  (0) 2023.10.27
제네릭(Generic)이란?  (0) 2023.10.25
Thread 구현과 실행 (Runnable vs Thread)  (0) 2023.10.25