创建给定类类型

时间:2018-05-16 11:15:19

标签: java object generics inheritance instance

我有一些子类,其中所有子类都由一个公共父类扩展。

我想要的是父类中的具体方法,该方法应该返回给定类类型的新对象。

这就是我的尝试。

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()方法也不是一种选择。有什么想法吗?

5 个答案:

答案 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() + '\'');
}