cyp*_*man 5 java generics reflection
我接受了一些我不知道的课程。其中一些显示为示例:
class Paper {}
class Bakery {}
class Cake extends Bakery {}
class ReflexiveBaker {
/**
* Create bakery of the provided class.
*
* @param order class of bakery to create
* @return bakery object
*/
public Object bake(Class order) {
// Add implementation here
}
}
Run Code Online (Sandbox Code Playgroud)
任务是根据需要重新设计方法签名类型并添加实现。烘焙方法应符合以下要求:
无论我尝试过什么,我都会收到一个错误: Main.java:: error: incompatible types: Object cannot be convert to Cake Cake cake = baker.bake(Cake.class);
我想出的最好的是:
public Object bake(Class<? extends Bakery> order) throws Exception {
return order.getDeclaredConstructor().newInstance();
}
Run Code Online (Sandbox Code Playgroud)
我知道这是错误的,但我完全被困在这里。有人可以解释一下发生了什么吗?
您的方法返回类型是java.lang.Object,编译器不能保证返回值是类型,Cake除非您通过添加这样的显式未经检查的强制转换来说服编译器。
Cake cake = (Cake) ReflexiveBaker.bake(Cake.class);
Run Code Online (Sandbox Code Playgroud)
这种未经检查的强制转换容易出错且笨拙。假设您有另一个名为 Bread 的类,它是 的子类型,Bakery并且您传递该类实例并期望 Cake 作为返回类型。上面的语句仍然可以编译,但ClassCastException在运行时抛出 a 。
更好的方法是使用有界类型参数来泛化该方法,这样它就只接受 的子类型Bakery并返回与提供的类对象的类型参数相同的类型。这是一个这样的尝试。
static class ReflexiveBaker {
public static <T extends Bakery> T bake(Class<T> order) {
try {
return order.getDeclaredConstructor().newInstance();
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException
| InvocationTargetException e) {
throw new AssertionError("Class could not be instantiated.", e);
}
}
}
Run Code Online (Sandbox Code Playgroud)