그것은 당신이 무엇에 따라 필요 할 수 있습니다. 다음과 같은 작업을 수행하려면 제한된 유형 매개 변수를 사용해야합니다.
public <T extends Shape> void addIfPretty(List<T> shapes, T shape) {
if (shape.isPretty()) {
shapes.add(shape);
}
}
여기에 a List<T> shapes
와 a T shape
가 있으므로 안전하게 할 수 shapes.add(shape)
있습니다. 선언 된 경우 안전하게 List<? extends Shape>
이동할 수 없습니다add
(a List<Square>
및 a 가있을 수 있기 때문에 Circle
).
따라서 제한된 유형 매개 변수에 이름을 지정하여 일반 메소드의 다른 곳에서 사용할 수 있습니다. 물론이 정보가 항상 필요한 것은 아니므로 유형 (예 :)에 대해 많이 알 필요가없는 경우 drawAll
와일드 카드만으로 충분합니다.
경계 유형 매개 변수를 다시 참조하지 않더라도 경계가 여러 개인 경우 경계 유형 매개 변수가 여전히 필요합니다. 다음은 Angelika Langer의 Java Generics FAQ 에서 인용 한 것입니다.
와일드 카드 바운드와 유형 매개 변수 바운드의 차이점은 무엇입니까?
와일드 카드는 하나의 경계 만 가질 수 있지만 유형 매개 변수는 여러 경계를 가질 수 있습니다. 와일드 카드는 하한 또는 상한을 가질 수 있지만 유형 매개 변수에 대한 하한은 없습니다.
와일드 카드 경계와 유형 매개 변수 경계는 둘 다 경계라고 불리며 부분적으로 유사한 구문을 갖기 때문에 종종 혼동됩니다. […]
구문 :
type parameter bound T extends Class & Interface1 & … & InterfaceN
wildcard bound
upper bound ? extends SuperType
lower bound ? super SubType
와일드 카드는 하한 또는 상한 중 하나만 가질 수 있습니다. 와일드 카드 경계 목록은 허용되지 않습니다.
constrast에서 유형 매개 변수는 여러 경계를 가질 수 있지만 유형 매개 변수에 대한 하한은 없습니다.
Effective Java 2nd Edition, Item 28의 인용문 : 제한된 와일드 카드를 사용하여 API 유연성을 높입니다 .
유연성을 극대화하려면 생산자 또는 소비자를 나타내는 입력 매개 변수에 와일드 카드 유형을 사용하십시오. […] PECS는 생산자 extends
, 소비자를 의미합니다. super
[…]
반환 유형으로 와일드 카드 유형을 사용하지 마십시오 . 사용자에게 추가적인 유연성을 제공하는 대신 클라이언트 코드에서 와일드 카드 유형을 사용하도록 강제합니다. 올바르게 사용 된 와일드 카드 유형은 클래스 사용자에게 거의 보이지 않습니다. 메서드가 허용해야하는 매개 변수를 받아들이고 거부해야하는 매개 변수를 거부하도록합니다. 클래스 사용자가 와일드 카드 유형에 대해 생각해야한다면 클래스의 API에 문제가있을 수 있습니다.
PECS 원칙을 적용하여 이제 addIfPretty
예제 로 돌아가서 다음을 작성하여 더 유연하게 만들 수 있습니다.
public <T extends Shape> void addIfPretty(List<? super T> list, T shape) { … }
이제 우리는 addIfPretty
a Circle
, a List<Object>
. 이것은 명백히 typesafe하지만 우리의 원래 선언은 그것을 허용 할만큼 충분히 유연하지 않았습니다.
관련 질문
요약
- 제한된 유형 매개 변수 / 와일드 카드를 사용하면 API의 유연성이 향상됩니다.
- 유형에 여러 매개 변수가 필요한 경우 경계 유형 매개 변수를 사용할 수밖에 없습니다.
- 유형에 하한이 필요한 경우 경계 와일드 카드를 사용할 수밖에 없습니다.
- "생산자"는 상한을, "소비자"는 하한을 가짐
- 반환 유형에 와일드 카드를 사용하지 마십시오.