2013-06-03 2 views
3

이것은 좁은 사례의 예입니다.Java Generics :: 유형 안전을 제공하지 못 했습니까?

아래의 코드를 살펴 : 나를 겁 무엇

class Holder<T> { 
    private T t; 
    public Holder(T t) { 
     this.t = t; 
    } 
    public T getValue() { 
     return t; 
    } 
} 

public class FooMain { 

    private static Object newHolder() { 
     return new Holder<Integer>(3); 
    } 

    public static void main(String args[]) { 
     Holder<String> hs = (Holder<String>) newHolder(); // line-18 
     String s = hs.getValue();       // line-19 
    } 
} 

피할 수 ClassCastException라인 (18)라인 (19)와하지에 발생됩니다 있다는 것입니다!

따라서 코드에 Holder<String> 유형의 객체를 사용하면 getValueString을 반환한다는 것을 보장하기에 충분하지 않습니다. 이 객체가 어떻게 구성되었는지도 조사해야합니다!

는 그 유형 소거 여기에 역할을 이해하지만 위의 의미가 얼마나 넓은 모르겠습니다. 내 특정 경우에는 newHolder -corresponding 방법은 외부 라이브러리에 정의 java.lang.Object 그래서 난이 캐스트를 할 필요가 반환됩니다.

+0

외부 라이브러리 메소드'Object newHolder()'에 의해 반환 된 객체가 'Holder '이 될 것이므로 컴파일러 경고에도 불구하고 명시 적으로 결과를 캐스팅한다고 가정합니다. 컴파일러에게 말하고있는 것을 의미합니다. * 나는 잘 압니다. * 그러나 당신의 가정은 틀린 것입니다. 그러한 결정을 내릴 때, 당신은 가정을해서는 안되지만 100 % 확실 할 것입니다. –

+0

관련 : http://stackoverflow.com/a/12209857/697449 –

답변

2

이 컴파일 할 때 당신은 경고를 얻을 것이다 결과를 초래할 수 있습니다. 이러한 캐스트를 작성하고 이러한 경고를 받으면 본질적으로 스스로 할 수 있습니다. 제네릭은 Java에서 지우개를 사용하여 구현되므로 일반 유형 정보는 런타임에 사라집니다. 이는 순전히 컴파일 시간 구조이므로, 런타임을 우회하면 나중에 런타임에 잘못된 캐스트를 수행 할 수 있습니다.

+0

다만 어떤 캐스트,하지만 잘못된 제네릭 형식은 *하지 *는'ClassCastException'와 빠른 실패합니다 의미 *되지 않은 * 캐스팅. –

2

제네릭 타입의 안전을 확인하기 위해 컴파일 시간 도구입니다. 런타임에는 type erasure 현재 유효성 검사가 없습니다. 그래서 Integer에서 String을 가져 오는 중 오류가 발생합니다. 캐스팅 때

BTW, 당신은 경고를 받아야합니다. 경고를 무시하면이 유형의 안전을 보장 할 수 없습니다 컴파일러를 의미 캐스트를 수행하고 있다는 말을 ...

관련 문제