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

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

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

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

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



답변

? 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 자체를 재정렬하기 위해 의 요소를 소비합니다 .


답변

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

상관 형 연장 Object(포함 Object)

위의 예는

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


답변

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.


답변

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

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

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

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


답변

영어로:

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

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


답변

물음표는 와일드 카드 를 정의하는 데 사용됩니다 . 이에 대한 Oracle 문서를 확인 하십시오 . http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html


답변