我不确定为什么Java要求我将makeInstance方法的返回强制转换为T?我究竟做错了什么?有没有更好的方法来实现这一目标?
public class Scratch {
public <T extends Base> T freshen(T instance) {
//why do I need to cast this to T
return makeInstance(instance.getClass());
}
public <T extends Base> T makeInstance(Class<T> type) {
try {
return type.newInstance();
} catch (InstantiationException ex) {
Logger.getLogger(Scratch.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Scratch.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static final class Base {
}
}
答案 0 :(得分:2)
Java希望您投射结果的原因是T
方法返回的makeInstance
不能保证与T
方法的freshen
相同。原因是getClass()
没有返回Class<T>
。相反,它会返回Class<? extends X>
,其中X
是静态类型instance
的删除,即Object
。编译器的推理链停止的地方:它不能从该调用推断返回类型为T
,要求你进行强制转换。
转换实例的另一种方法是强制转换类,如下所示:
return makeInstance((Class<T>)instance.getClass());
答案 1 :(得分:1)
问题的根本原因是&#34;键入erasure&#34;:当Java编译器编译freshen()
方法的主体时,它基本上用其上限替换T
类型,即:Base
。
所以这就是编译器正在做的理由:
- instance
类型为Base
(正如我所说,T
已替换为Base
)
- 对.getClass()
类型的变量调用Base
,因此此调用的返回值为Class<? extends Base
&gt;
- 因此,从编译器的角度来看,传递给makeInstance()
的参数类型为Class<? extends Base>
。因此,T
内的makeInstance()
也是Base
=&gt;该方法返回Base
答案 2 :(得分:0)
您可以使用以下方法解决此问题。
public class Scratch<T extends Base> {
public T freshen(T instance) {
// No need to cast this to T
return makeInstance(instance.getClass());
}
public T makeInstance(Class<T> type) {
try {
return type.newInstance();
} catch (InstantiationException ex) {
Logger.getLogger(Scratch.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Scratch.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static final class Base {
}
}
希望这有帮助。