2014-06-11 3 views
2
class Test<G extends String>{ 
    public G test(){return null;} 
    public List<G> tests(){return new ArrayList<>();} 
} 
public void doTest(Test t){ 
    //works fine 
    String str = t.test(); 
    //Compile error: expected String found Object 
    str = t.tests().iterator().next(); 
} 

Type G가 String 하위 클래스에 바인딩되었으므로 마지막 줄에서 Object 대신 String 인스턴스를 반환하고 싶습니다. 캐스팅 이외의 다른 방법이 있습니까?왜 정의되지 않은 제네릭 형식 컬렉션은 다른 클래스에 바인딩되어 있어도 Object를 기본값으로 사용합니까?

+4

때문에 원시 유형의 일반 바인딩 당신은 처음부터 고려하지 않습니다 당신처럼 결코 정의되지 수업을 전혀 제네릭으로 만들지 않았습니다. 이것은 부분적으로는 Java 1.5 이전에 제네릭이 Java에 존재하지 않았기 때문에 설명하는 동작을 구현할 방법이 없었기 때문입니다. – awksp

+0

이 경우 t.test()도 Object를 반환하지 않아야합니까? – Gus

+0

음 ... 흥미로운 점. 처음에는 그걸 놓쳤습니다. 이 경우에는 반환 된'ArrayList'가 원시 타입이 될 것입니다. 't.test()'가'String'을 리턴하는 이유를 확실히 모릅니다. – awksp

답변

5

아니요, 유형이 지워졌습니다. 당신은 유형의 삭제에 대한 두 가지 다른 규칙으로 실행하고 - JLS section 4.6에서 :

  • 파라미터 화 된 형태의 삭제 (§4.5) G는 | | G.
  • 유형 변수 (§4.4)의 지우기는 가장 왼쪽 경계의 지우기입니다.

그래서 List<G>의 삭제는 List이지만, G의 삭제는 String이다 - 최초의 할당이 작동하는 이유입니다.

컴파일이 코드를 얻기 위해해야 ​​할 일은 당신의 매개 변수에 와일드 카드를 사용할 수 있습니다 :

public void doTest(Test<?> t) 
+0

음, 호기심 -'next() '에 대한'?'의 리턴 타입은 무엇을 의미합니까? 유형이 제대로 작동하지 않으면 런타임 예외가 발생합니까? 또는'G'가 항상'String'이기 때문에 안전합니까? – awksp

+0

@ user3580294 :'G'는 항상'String'과 대입 호환이 가능하기 때문에 안전합니다 ... 기본적으로'Iterator 을 호출하여'next()'를 호출합니다. –

+0

이상하게도 이클립스는'iterator()'는 약간의 혼란스러워하는 Iterator 을 리턴하지만 응답은 의미가있다. – awksp