2016-11-02 2 views
3

편집 : 예, 중복 될 수 있습니다. 그러나 다른 질문은 "전기 톱이란 무엇인가? 그리고 어떻게 사용합니까?"와 비슷합니다. 내 것은 마치 "이 기계로 구멍을 뚫으 려하고 있는데 작동하지 않는다. 무슨 일이야?" 물론 대답은 "전기 톱을 사용하지 마십시오!"입니다. 전기 톱을 다루는 것을 알게되면 쉽게 발견 할 수 있습니다.Java Generics : "중첩 된"형식 매개 변수?

하지만 내 질문이 "원시 유형 대 와일드 카드"와 관련되어있어 그 질문을 찾지 못했습니다. 어쩌면이 질문은 나 같은 다른 사람들에게도 유용 할 수 있습니다.

원래의 질문 :의 내가 내 사용자 인터페이스에서 항목을 나타내는 다음과 같은 데이터 구조에 있다고 가정 해 봅시다 :

public static abstract class EpgRowItem<T> extends RowItem<Pair<String, T>> { 

    public EpgRowItem(Pair<String, T> value) { 
     super(value); 
    } 
} 

public static final class EpgRowProgramItem extends EpgRowItem<Program> { 

    public EpgRowProgramItem(Pair<String, Program> value) { 
     super(value); 
    } 
} 

public static final class EpgRowOtherDateItem extends EpgRowItem<LocalDate> { 

    public EpgRowOtherDateItem(Pair<String, LocalDate> value) { 
     super(value); 
    } 
} 

: 이제

public static abstract class RowItem<T> { 

    public final T value; 

    public RowItem(T value) { 
     this.value = value; 
    } 
} 

을, 나는 다음을 수행 싶습니다 즉, EpgRowItemRowItem이며 Pair을 포함하며 그 중 첫 번째 멤버는 항상 String이고 두 번째 멤버는 아무 것도 될 수 있습니다. 또한 EpgRowProgramItemEpgRowItem이며 두 번째 멤버는 Program입니다. 마찬가지로, EpgRowOtherDateItemEpgRowItem이고 두 번째 멤버는 LocalDate입니다. 나는이 내 코드에 다른 장소에있을 때까지

이 작동하는 것 같다 :

List<OverlayPresenter.EpgRowItem> programs = ...; 
OverlayPresenter.EpgRowItem epgRowItem = programs.get(0); 
String channelId = epgRowItem.value.first; // DOESN'T COMPILE?! 

내가 컴파일러가 epgRowItem.value 항상 Pair<String, ?>해야합니다 알고 있어야한다고 생각한다, 그 결과 epgRowItem.value.first는 항상 String해야합니다.

사실, 첫 번째 부분도 알지 못합니다. 이자형. 다음 중 하나도 컴파일되지 않습니다.

Pair<String, ?> pair = epgRowItem.value; // epgRowItem.value is an Object?! 

무엇이 잘못 되었나요? 나는 자바의 generics를 너무 많이 묻는가? 당신은 원시 타입 EpgRowItem을 사용하고 있기 때문에

+0

그래, 내가 물론 복제본입니다. 그러나 "다른 방향으로 돌아가는"질문 - 높은 수준의 키워드가 아닌 구체적인 문제로 시작 - 나는 여전히 유효한 질문이며 다른 사람들에게 유용 할 수 있다고 생각합니다. –

답변

4

당신은 곤경에 얻을 (원시 유형이 유형의 매개 변수를 지정하지 않은 파라미터 화 된 형태이며,이 때문에 이전 버전과 자바 1.4과의 호환성과 나이의 존재) :

List<OverlayPresenter.EpgRowItem> programs = ...; 
OverlayPresenter.EpgRowItem epgRowItem = programs.get(0); 

참조 : What is a raw type and why shouldn't we use it?

는 형식 매개 변수를 사용하거나 적어도 와일드 카드 : 지금은 답을 알고,

List<OverlayPresenter.EpgRowItem<?>> programs = ...; 
OverlayPresenter.EpgRowItem<?> epgRowItem = programs.get(0); 
String channelId = epgRowItem.value.first; // OK 
+0

아, 그거 재미 있어요. 지금까지는 Java Generics 사용에있어서 항상 안전하다고 생각했지만, 그것은 저에게 새로운 것입니다. 고마워요! –