我有一些子类,其中所有子类都由一个公共父类扩展。
我想要的是父类中的具体方法,该方法应该返回给定类类型的新对象。
这就是我的尝试。
class Vehicle {
public <T> T get(Class<T> type){
//return new T();
}
}
class Car extends Vehicle {
}
class Van extends Vehicle {
}
高于get(...)
方法
return new T();
语句给出了编译错误,
意外类型
要求:班级 发现:类型参数T
我无法直接创建子类的对象,
new Car();
出于某种原因。可以有任意数量的子类,因此在每个子类中重写get()
方法也不是一种选择。有什么想法吗?
答案 0 :(得分:5)
您可以使用Class.newInstance()
实例化Class
对象。
public <T> T get(Class<T> type) throws InstantiationException, IllegalAccessException {
return type.newInstance();
}
但是这个类必须有一个无参数的构造函数;它可能会抛出异常。
答案 1 :(得分:1)
new T()
是类型的占位符,而不是类型;因此,您无法拨打T
,因为type
中没有值。
值在Class
,您必须使用该变量。
重要的是要记住,在泛型系统中,占位符不是Java类型意义上的类型。他们遵循关于如何约束(超级等)的不同规则。它们在应用时(编译时)具有不同的绑定。这些特征意味着它们无法与Java的类型系统协调,即使它们(在某种程度上)控制它。
现在您有一个type
对象作为值,绑定到变量Class
。您可以使用Java的工具从type
中的<router-link :to="{name: 'ShowPost', params: {slug: post.slug, id:post.id}}">{{ post.title.rendered }}</router-link>
对象创建新实例。
答案 2 :(得分:1)
您可以使基类具有通用性,因此您可以使用get()
方法的正确返回类型。
abstract class Vehicle<T extends Vehicle> {
public abstract T get();
}
class Car extends Vehicle {
@Override
public Car get() {
return new Car();
}
}
但是,这并不会强制Car
实际返回Car
;它可以免费返回Van
。
答案 3 :(得分:0)
修改你的get方法,如下面的代码所示:
public <T> T get(Class<T> type) throws InstantiationException, IllegalAccessException {
return type.newInstance();
}
答案 4 :(得分:0)
如果你在Car和Van类中有默认构造函数,那么你可以使用这种方法:
public static <T extends Vehicle> T get(Class<T> cls) throws Exception {
return cls.getConstructor().newInstance();
}
或者,作为替代,这个(它看起来比我更好;但我没有反对前一个):
public static <T extends Vehicle> T get(Class<T> cls) {
if (cls.isAssignableFrom(Car.class))
return (T)new Car();
if (cls.isAssignableFrom(Van.class))
return (T)new Van();
throw new RuntimeException("Unknown class '" + cls.getSimpleName() + '\'');
}