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 |