2013-12-22 2 views
1

와일드 카드로 매개 변수화 된 유형으로 원시 유형을 변환하면 예외가 발생하는 문제가 있습니다. 원시 형식은 사용하지 않는 것이 좋습니다. 그러나 대안도 원하지 않는 것처럼 보입니다.와일드 카드 유형 불일치 대 원시 유형

public static abstract class A<T> { 
    T t; 
    public abstract void add(T t2); 
} 
public static class C extends A<Double> { 
    @Override public void add(Double t2) { t += t2; } 
} 
public static class D extends A<String> { 
    @Override public void add(String t2) { t.concat(t2); } 
} 

그리고 다음 코드 :

public static void main(String[] args) { 
    A<?>[] as = new A[2]; 
    as[0] = new C(); 
    as[1] = new D(); 
    for (A<?> a: as) 
     a.add(a.t);  // results in a type mismatch exception 
    for (A<?> a: as) 
     insideFor(a); // is not so neat 
    for (A a: as) 
     a.add(a.t);  // makes use of raw types 
} 
private static <T> void insideFor(A<T> a) { 
    a.add(a.t); 
} 

는 어떻게해야합니까

는 다음과 같은 클래스를 고려?

+0

매개 변수화 된 유형으로 달성하려는 것은 무엇입니까? 당신이 제시 한 옵션은 거의 모든 것입니다. –

+0

'A '을 사용한다면, 본질적으로 "무엇이든"이라고 말합니다. 유형을 모르기 때문에 * 아무것도 * 예상하는 모든 메소드에 객체를 전달할 수 없습니다. – Darkhogg

+3

예, [0]은 Double을 허용하고 [1] 만 String을 받아 들일 수 있어야하므로이 코드를 안전하게 만들 수는 없습니다. 당신이 그것이 일어나고 있는지 확인하도록 지정할 수있는 유형이 없습니다. 이것은'A [] as'는 각각의 as [i]에 Object를 확장하는 T 타입이 있다는 것을 의미하지는 않습니다. [i]는 A 입니다. 오히려 그것은 Object를 확장하는 T 형이 있다는 것을 의미합니다. 즉, [i]가 A 인 것처럼 [i]와 같이 각각 확장됩니다. 여기서'T'는'Object'입니다. –

답변

1

두 번째 방법을 ("그렇게 단정하지 것은") 그 일을의 표준 방법입니다. 이를 캡처 도우미이라고합니다. "로컬"유형 변수를 도입 할 수 있도록 캡처 기능을 이용합니다. 도우미 메서드는 보통 private으로되어 있으므로 외부 코드가 해당 코드를 알고 있지 않아도됩니다.

P. S은 어디에서도 사용되지 않습니다

+0

응답 해 주셔서 감사합니다. 실제로 그것은 '사적 (private)'이었을 것이고,'S'는 내가 일하고있는 좀 더 정교한 모범의 사례였다. –

0

자바 제네릭에는 일반적으로 좋은 디자인으로 피할 수있는 몇 가지 제한 사항이 있습니다. 이 경우 I는 클래스에 "addInner()"방법을 추가합니다 :

public static abstract class A<T> { 
    T t; 
    public abstract void add(T t2); 
    public void addInner(){ 
     this.add(this.t); 
    } 
}