Reputation: 85
I am given some classes that are unknown to me. Some of them are shown as an example:
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
}
}
The task is to redesign method signature types if needed and to add implementation. The bake method should conform to the following:
Whatever I've tried I'm getting an error: Main.java:: error: incompatible types: Object cannot be converted to Cake Cake cake = baker.bake(Cake.class);
The best I've come up with is this:
public Object bake(Class<? extends Bakery> order) throws Exception {
return order.getDeclaredConstructor().newInstance();
}
I know that it's wrong but I'm completely stuck here. Could someone please explain what's going on?
Upvotes: 5
Views: 307
Reputation: 21124
Your methods return type is java.lang.Object
and the compiler can't vouch that the return value is of type Cake
unless you convince the compiler by adding an explicit unchecked cast like this.
Cake cake = (Cake) ReflexiveBaker.bake(Cake.class);
This unchecked cast is error prone and awkward. Say you have another class called Bread that is a subtype of Bakery
and you pass that class instance expecting Cake as the return type. The above statement still compiles, but throws a ClassCastException
at runtime.
A much better approach is to generify the method using a bounded type parameter such a way that it accepts only sub types of Bakery
and returns the same type as the type parameter of the class object provided. Here's one such attempt.
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);
}
}
}
Upvotes: 6