我正在尝试从xml反序列化对象时捕获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.
}
然而这并不会因为异常没有被抓住。你会建议什么?
答案 0 :(得分:11)
问题中的代码应该为您提供未经检查的投射警告。听听-Xlint。
所有编译器都知道T是它的边界,它可能没有(除了显式扩展Object和null类型的super)。因此,运行时的强制转换是(对象) - 不是很有用。
您可以做的是传入参数化类型的Class实例(假设它不是通用的)。
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) {
...
}
}
}
或者作为通用方法:
public <T> T restore(Class<T> clazz, String from) {
...
try {
restoredItem = clazz.cast(decoder.readObject());
...
答案 1 :(得分:3)
不会有任何ClassCastException,除非你的T有一些基础:
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;
}
}
在上面的例子中,在前5次调用cast和castBaseNumber时没有ClassCastException。只有第6次调用才会抛出ClassCastException,因为编译器有效地将cast()转换为return(Object)o,并将castBaseNumber()转换为返回(Number)o;。你写的文
String s = GenericsTest.<Long> cast("Hallo");
你会得到一个ClassCastException,但不是在cast方法中,而是在s的赋值中。
因此我认为,你的“T”不仅仅是“T”,而是“T延伸某事”。所以你可以查一下:
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
对于这种情况,只有汤姆的建议可能有所帮助。
答案 2 :(得分:0)
好吧,我不能使用instanceof
运算符,因为该方法是参数化的:
public T restore(String from){
...
restoredItem = (T) decoder.readObject();
...
}
Java中的泛型只是编译时间。
答案 3 :(得分:0)
如果你不能使用instanceof,你可以在Class
上使用isAssignableFrom方法