와일드 카드, 지네릭 메서드
와일드 카드 <?>
- 하나의 참조 변수로 대입된 타입이 다른 객체를 참조 가능
일반적으로 지네릭 클래스는 참조변수에 대입된 타입과, 생성자에 대입된 타입이 일치해야 한다.
일치하지 않으면 에러가 발생한다.
그런데, 우리는 다형성을 배웠기 때문에 하나의 참조변수로 여러 객체를 가리키고 싶을 때가 있다.
그런데 참조변수에 대입된 타입과 생성자에 대입된 타입이 일치해야 한다는 것이 부담이다.
그래서 이 답답함을 없애기 위해 나온 것이 와일다 카드<?>이다.
와일드 카드를 사용하면, 참조변수에 대입된 타입과 생성자에 대입된 타입이 일치하지 않아도 OK다.
와일드 카드는 용법이 있는데, 주로 <? extends T> 이 방법을 많이 사용한다.
위의 예시 코드를 기준으로, 생각해 보았을 때, 최고 조상이 Object이고, Porudct의 자손으로 Tv가 있다.
<? extends T>는 T를 포함하여 그 이후의 자손들이 가능하다.
위 그림은 T가 Tv인 경우이다. Tv를 포함한 그 자손들이가능하다.
<? super T>는 T와 그 조상들만 가능하다.
위 그림은 T가 Tv인 경우이다. Tv를 포함한 그 모든 조상이 가능하다.
<?>는 제한 없이 모든 타입이 가능하다. <? extends Object>와 동일하다.
예를 들어, <? extends Product> 를 하면 Product와 그 자손들이 가능하다. (Product, Tv, Audio)
- 메서드의 매개변수에 와일드 카드를 사용
메서드의 매개변수에도 와일드 카드를 사용할 수 있다.
위의 코드처럼 사용하면,
대입된 타입이 Fruit인 경우, Apple인 경우 둘다 box에 들어갈 수 있다.
만약 와일드 카드 <? extends Fruit>를 사용하지 않으면, Fruit만 들어갈 수 있었을 것이다.
<? extends T>는 T와 그 자손이 가능하기 때문의 위의 예제코드는 Fruit와 그 자손들이 다 가능한 것이다.
[Ex12_4]
지네릭 메서드
- 지네릭 타입이 선언된 메서드(타입 변수는 메서드 내에서만 유효)
지네릭 메서드는, 메서드에 타입변수가 선언된 것이다.
클래스에 타입변수가 선언되면 지네릭 클래스 인 것 처럼 지네릭 메서드는 메서드 내에서 타입 변수가 선언된 것이다.
- 클래스의 타입 매개변수<T>와 메서드의 타입 매개변수 <T>는 별개
위의 예제 코드처럼 지네릭 클래스의 타입변수와 지네릭 메서드의 타입변수가 겹치면,
지네릭 메서드 안에서의 <T>는 가까운 곳에서 선언된 지네릭 메서드의 타입 변수가 더 우선된다.
iv와 lv의 관계와 똑같다. 메서드 내에서는 가까우므로 lv가 더 우선하는 것과 같다.
- 메서드를 호출할 때마다 타입을 대입해야(대부분 생략 가능)
지네릭 클래스는 객체를 생성할 때마다, 타입을 대입 하는데,
지네릭 메서드는 메서드를 호출 할 때마다 타입을 대입해야 한다.(대부분 생략가능하기도 하다)
즉, 지네릭 메서드를 호출할 때마다 다른 타입을 대입할 수 있는 것이다.
예를 들어서 <T extends Fruit> makeJuice라는 메서드가 있을 때,
makeJuice라는 메서드를 호출할 때마다 타입을 대입해야 한다.
makeJuice메서드는 지네릭 메서드인데,
타입 변수가 <T extends Fruit>로 타입 T가 Fruit의 자손이어야 한다고 제한되어 있으므로
makeJuice 메서드를 호출 하며 타입 변수를 대입할때 해당 타입 변수로는 Fruit이나 Fruit의 자손만 올 수 있다.
그리고 해당 메서드의 매개변수의 <FruiteBox<T> 의 <T>는 가까운 <T>와 일치하기 때문에 메서드의 <T>와 일치한다.
따라서 FruitBox<Fruit>();, FruitBox<Apple>(); 객체가 가능하다.
- 메서드를 호출할 때 타입을 생략하지 않을 때는 클래스 이름 생략 불가
메서드를 호출할 때 타입을 생략하지 않을 때는 클래스 이름을 생략할 수 없다.
이경우에는,
와일드 카드를 사용하지 않은 지네릭 메서드와, 와일드 카드를 사용한 지네릭메서드 두 메서드는 같은 의미이다.
잘 따져보면 의미가 같은 것을 알 수 있다.
그런데,
와일드 카드는 하나의 참조변수로 대입된 타입이 다른 여러타입의 지네릭 객체를 다룰 수 있게 하기 위함이고,
지네릭 메서드는 지네릭 클래스 처럼 호출할 때마다 다른 타입을 대입할 수 있는 것이다.
둘의 목적과 용도가 조금 다르다.
와일드 카드를 사용할 수 없을 때 지네릭 메서드를 사용하는 경우가 많다.
'JAVA' 카테고리의 다른 글
열거형 (0) | 2022.05.08 |
---|---|
지네릭 타입의 형변환, 지네릭 타입의 제거 (0) | 2022.05.07 |
제한된 지네릭 클래스, 지네릭스의 제약 (0) | 2022.05.04 |
Iterator, HashMap과 지네릭스 (0) | 2022.05.04 |
지네릭스 용어, 지네릭 타입과 다형성 (0) | 2022.05.04 |
댓글
이 글 공유하기
다른 글
-
열거형
열거형
2022.05.08 -
지네릭 타입의 형변환, 지네릭 타입의 제거
지네릭 타입의 형변환, 지네릭 타입의 제거
2022.05.07 -
제한된 지네릭 클래스, 지네릭스의 제약
제한된 지네릭 클래스, 지네릭스의 제약
2022.05.04 -
Iterator, HashMap과 지네릭스
Iterator, HashMap과 지네릭스
2022.05.04