Java:嵌套递归泛型

前端之家收集整理的这篇文章主要介绍了Java:嵌套递归泛型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一组扩展一些基本实体的类.此集合中的类也可以相互扩展,从而创建嵌套层次结构.

我的目标是让所有类都可以访问创建自己的新实例的方法.我想在我的基本实体中实现此方法,以便所有扩展类继承此方法.

以下是为我的模式定义的三个示例类:

BaseEntity.java

public abstract class BaseEntity<E extends BaseEntity> {

    Class<E> clazz;

    public BaseEntity(Class<E> clazz) {
        this.clazz = clazz;
    }

    public E getNewInstance() throws IllegalAccessException,InstantiationException {
        return clazz.newInstance();
    }

}

Collection.java

public class Collection<E extends Collection> extends BaseEntity<E> {

    public Collection() {
        super(Collection.class); 
        // compiler error: BaseEntity (java.lang.Class<E>) in BaseEntity cannot be applied to
        //                            (java.lang.Class<Collection>)
    }

    public Collection(Class<E> clazz) {
        super(clazz);
    }

}

Document.java

public class Document extends Collection<Document> {

    public Document() {
        super(Document.class);
    }

}

有了这个设置,我希望能够做到这样的事情:

Collection c = new Collection();
c = c.getNewInstance(); // compiler error

Document d = new Document();
d = d.getNewInstance();

Collection cd = new Document();
cd = cd.getNewInstance(); // compiler error

但请注意,Collection.java的默认构造函数中存在编译器错误.我不确定为什么会造成这种情况,我认为这也会导致示例main方法中的编译器错误.我做错了什么,如何解决这个问题?

请注意,这是一个人为的例子,涉及我正在努力解决的更大问题.我知道这个实现本身看起来很傻.

解决方法

收集和LT,E …>是一种泛型类型,但您的Collection c是原始类型.这意味着它的所有方法都将被视为原始类型,这意味着它们将返回任何泛型的擦除.

您的基类声明为BaseEntity< E extends BaseEntity>,这意味着在此方法中:

E getNewInstance()

擦除是

BaseEntity getNewInstance();

这意味着c.getNewInstance()返回一个BaseEntity,而不是一个Collection,这是编译错误的来源.

另一方面,文档不是通用类.这意味着擦除在编译时无关紧要(出于这些目的),并且getNewInstance()返回E表示的类型,在本例中为Document.因此,d.getNewInstance()的返回类型为Document,因此该行编译正常.

顺便说一句:每当你有递归泛型时,你应该确保在递归中考虑泛型.例如,在这一行:

BaseEntity<E extends BaseEntity>

您已将BaseEntity定义为泛型类 – 但随后立即忽略其在E扩展BaseEntity中的泛型.那条线应该是:

BaseEntity<E extends BaseEntity<E>>

猜你在找的Java相关文章