2008-10-09 7 views
6

XML에서 개체를 deserialize 할 때 ClassCastException을 잡으려고합니다.ClassCastException을 잡는 방법은 무엇입니까?

그래서,

try { 
    restoredItem = (T) decoder.readObject(); 
} catch (ClassCastException e){ 
    //don't need to crash at this point, 
    //just let the user know that a wrong file has been passed. 
} 

그럼에도 불구하고이 예외가 잡히지 않습니다하지 않으므로

. 너는 무엇을 제안 하겠는가?

public T restore(String from){ 
... 
restoredItem = (T) decoder.readObject(); 
... 
} 

을 그리고 자바 제네릭 컴파일 타임에만 있습니다

+0

다시 태그에 일지 어떨지 방법을 사용할 수 있습니다. –

답변

8

질문에있는 코드는 검사되지 않은 경고 메시지를 표시합니다. -Xlint를 들어라.

모든 컴파일러는 T가 그 경계가 아님을 알고 있습니다 (명시 적으로 확장 된 Object 및 null 유형의 수퍼 이외). 그래서 런타임시에 캐스트가 (Object) - 그리 유용하지는 않습니다.

매개 변수화 된 유형의 클래스 인스턴스를 전달할 수 있습니다 (일반형이 아닌 것으로 가정).

가 에게 는
public <T> T restore(Class<T> clazz, String from) { 
     ... 
     try { 
      restoredItem = clazz.cast(decoder.readObject()); 
      ... 
0

음, 방법은 매개 변수화 한대로 나는 instanceof 연산자를 사용할 수 없습니다.

+0

T에 대한 캐스트가 실제로 메서드 자체가 아니라 호출자에 의해 수행되었다고 제안하지 않을까요? –

+0

잘 모르겠습니다. 빠른 해킹으로 개체를 복원 (..)에서 반환하고 더 높은 수준에서 instanceof 검사를 수행합니다. 제네릭 관련이 없습니다 (어쨌든 도움이되지 않음). 아직도, 이것은 추한 것입니다. – yanchenko

3

당신의 T는 어떤 기준이있는 경우를 제외한 모든 ClassCastException이있을 수 없습니다 : 위의 예에서

public class GenericsTest 
{ 
    public static void main(String[] args) 
    { 
     System.out.println(cast(Integer.valueOf(0))); 
     System.out.println(GenericsTest.<Long> cast(Integer.valueOf(0))); 
     System.out.println(GenericsTest.<Long> cast("Hallo")); 

     System.out.println(castBaseNumber(Integer.valueOf(0))); 
     System.out.println(GenericsTest.<Long> castBaseNumber(Integer.valueOf(0))); 
     System.out.println(GenericsTest.<Long> castBaseNumber("Hallo")); 
    } 

    private static <T extends Number> T castBaseNumber(Object o) 
    { 
     T t = (T)o; 
     return t; 
    } 

    private static <T> T cast(Object o) 
    { 
     T t = (T)o; 
     return t; 
    } 
} 

을있을 것

class MyReader<T> { 
    private final Class<T> clazz; 
    MyReader(Class<T> clazz) { 
     if (clazz == null) { 
      throw new NullPointerException(); 
     } 
     this.clazz = clazz; 
    } 
    public T restore(String from) { 
     ... 
     try { 
      restoredItem = clazz.cast(decoder.readObject()); 
      ... 
      return restoredItem; 
     } catch (ClassCastException exc) { 
      ... 
     } 
    } 
} 

또는 일반적인 방법으로

cast 및 castBaseNumber에 대한 처음 5 개의 호출에는 ClassCastException이 없습니다. 컴파일러가 cast()를 return (Object) o로, castBaseNumber()를 return (Number) o로 효과적으로 변환하기 때문에 6 번째 호출 만 ClassCastException을 throw합니다. 당신이 쓴다

String s = GenericsTest.<Long> cast("Hallo"); 

당신은 ClassCastException을 얻을 수는 있지만 캐스트 방법은 없지만 s에 할당 할 때.

따라서 "T"는 "T"가 아니라 "T extends Something"이라고 생각합니다. 따라서 다음을 확인할 수 있습니다 :

Object o = decoder.readObject(); 
if (o instanceof Something) 
    restoredItem = (T) o; 
else 
    // Error handling 

그러나이 방법은 나중에 클래스를 사용할 때 오류가 발생할 수 있습니다.

public Reader<T extends Number>{...} 

Long l = new Reader<Long>("file.xml").getValue(); // there might be the ClassCastException 

이 경우에는 Tom의 조언 만 도움이 될 수 있습니다. 당신이 instaceof 사용할 수없는 경우

0

당신은 일반적인 예외 releated 태그를 사용하는 클래스

관련 문제