Java 제네릭 형식 매개 변수의 물음표는 무엇을 의미합니까?


216

이것은 스탠포드 파서와 함께 제공되는 일부 예제에서 가져온 작은 코드입니다. 저는 약 4 년 동안 Java로 개발해 왔지만이 코드 스타일이 무엇을 나타내는 지에 대해 아주 잘 이해 한 적이 없습니다.

List<? extends HasWord> wordList = toke.tokenize();

코드의 세부 사항에 대해 걱정하지 않습니다. 내가 혼란스럽게하는 것은 일반적인 표현이 영어로 전달 해야하는 것입니다.

누군가 나에게 이것을 설명 할 수 있습니까?


답변:


226
? extends HasWord

"확장되는 클래스 / 인터페이스"를 의미합니다 HasWord. 다시 말해, HasWord그 자체 또는 그 자식 중 하나는 기본적으로 instanceof HasWordplus 와 함께 작동하는 모든 것입니다 null.

보다 기술적 인 용어로, 139 페이지에서 시작하는 Effective Java 3rd Edition? extends HasWord 의 항목 31에서 다루는 경계 와일드 카드 입니다. 2nd Edition과 동일한 장이 온라인으로 PDF로 제공됩니다 . 경계 와일드 카드의 부분은 134 페이지에서 시작하는 항목 28입니다.

업데이트 : Oracle이 한동안 그것을 제거한 후 PDF 링크가 업데이트되었습니다. 이제는 Queen Queen University of London의 전자 공학 및 컴퓨터 과학 학교에서 주최하는 사본을 가리 킵니다.

업데이트 2 : 와일드 카드를 사용하려는 이유에 대해 좀 더 자세히 살펴 보겠습니다.

서명을 전달할 것으로 예상되는 메소드를 선언하면 전달할 List<HasWord>수있는 유일한 것은 List<HasWord>입니다.

그러나 서명이 있었다면 대신 List<? extends HasWord>전달할 수 List<ChildOfHasWord>있습니다.

List<? extends HasWord>와 사이에는 미묘한 차이가 List<? super HasWord>있습니다. Joshua Bloch가 말했듯이 PECS = 생산자 확장, 소비자 슈퍼.

이것이 의미하는 것은 메소드가 데이터를 가져 오는 콜렉션을 전달하는 경우 (즉, 콜렉션이 사용하는 메소드에 대한 요소를 생성하는 경우) 사용해야합니다 extends. 메소드가 데이터를 추가하는 콜렉션을 전달하는 경우 (즉, 콜렉션이 메소드를 작성하는 요소를 소비하는 경우)를 사용해야합니다 super.

혼란 스러울 수 있습니다. 그러나 Listsort명령 에서 볼 수 있습니다 (이것은 Collections.sort의 두 가지 버전의 바로 가기입니다). 을 복용하는 대신 Comparator<T>실제로을 사용합니다 Comparator<? super T>. 이 경우 비교기는 ListList 자체를 재정렬하기 위해 의 요소를 소비합니다 .


17
"Instanceof와 함께 작동하는 모든 것"-null 값. 점검 할 경우 null 값은 false를 반환합니다.
Eyal Schneider 2016 년

12
인터페이스를 잊지 마십시오. ? 수업을 대표 할 필요는 없습니다!
Mark Peters

9
List<HasWord>정확히 당신이 설명하는 것입니다 : true xx instanceof HasWord반환 하는 객체 를 포함하는 목록 및 null. 이를 위해 와일드 카드가 필요하지 않습니다. 와일드 카드는이 유형이의 하위 유형 인 한 실제로 다른 유형의 목록 일 수도 있음을 의미합니다 HasWord. (늦은 의견에 대해 죄송합니다.)
Paŭlo Ebermann

1
PDF 링크가 작동하지 않는 것 같습니다. 그러나 이것은 나에게 유용했습니다. docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
user1338062

작년에 @ user1338062가 게시되어 PDF 링크가 작동하지 않는다는 메시지를받지 못한 메시지가 나타나지 않았습니다. 지금 수정했습니다. 나는 또한 책 자체에 대한 링크를 추가했다.
Powerlord

65

물음표는 '모든 유형'에 대한 부호입니다. ?혼자 의미

상관 형 연장 Object(포함 Object)

위의 예는

확장하거나 구현하는 모든 유형 HasWord( 비추 상 클래스 인 HasWord경우 포함 HasWord)


2
무슨 public Set<Class<?>> getClasses()뜻입니까? 차이점은 Set<Class>무엇입니까? 보고 있습니다 javax.ws.rs.core.Application.
볼트

14

List<? extends HasWord>HasWord를 확장하는 구체적인 클래스를 허용합니다. 다음 수업이 있다면 ...

public class A extends HasWord { .. }
public class B extends HasWord { .. }
public class C { .. }
public class D extends SomeOtherWord { .. }

... wordList두 클래스가 동일한 부모를 확장하거나 null인스턴스 검사에 실패 하기 때문에 As 또는 B 또는 둘의 혼합 목록 만 포함 할 수 있습니다 HasWorld.


8
구체적 일뿐만 아니라 추상 서브 클래스도 있습니다.
bloparod 2018 년

2
구체적이고 추상적 인 서브 클래스뿐만 아니라 서브 인터페이스 : List<? extends Collection<String>> list = new ArrayList<List<String>>();.
Mark Peters

2
이를 위해 와일드 카드가 필요하지 않습니다. 실제로 : List<HasWord>이것도 마찬가지입니다. 여기서 요점은이 변수가 포함 할 수 있다는 것입니다 List<A>또는 List<B>A와뿐만 아니라 List<HasWord>.
Paŭlo Ebermann

12

아마도 "진정한 세계"의 예가 도움이 될 것입니다.

직장에서 우리는 다른 맛으로 나오는 쓰레기통을 가지고 있습니다. 모든 쓰레기통에는 쓰레기가 들어 있지만 일부 쓰레기통은 전문가이며 모든 쓰레기통을 사용하지는 않습니다. 그래서 우리는이 Bin<CupRubbish>Bin<RecylcableRubbish>. 타입 시스템은 내가이 HalfEatenSandwichRubbish타입들 중 어느 것에도 넣을 수 없도록해야 하지만, 일반 쓰레기통에 들어갈 수 있습니다 Bin<Rubbish>. 호환되지 않는 쓰레기를 넣을 수 없으므로 전문화 될 수 있는 Bin에 대해 이야기하고 싶다면 그럴 Rubbish것입니다 Bin<? extends Rubbish>.

(참고 : ? extends읽기 전용을 의미하지는 않습니다. 예를 들어, 적절한 예방 조치를 취하면 알 수없는 특수 용기에서 쓰레기를 꺼낸 후 나중에 다른 장소에 다시 넣을 수 있습니다.)

그것이 얼마나 도움이되는지 확실하지 않습니다. 다형성이 존재하는 포인터 대 포인터는 완전히 명확하지 않습니다.


5

영어로:

그것은의 List클래스를 확장 어떤 종류의 HasWord를 포함하여,HasWord

일반적으로 ?제네릭은 모든 클래스를 의미합니다. 그리고이 extends SomeClass객체는 그 객체가 확장되어야한다는 것을 지정합니다 SomeClass.


1
실제로 class 대신 type을 입력하십시오 . 이것은 인터페이스에서도 잘 작동합니다.
Paŭlo Ebermann

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.