Java:嵌套递归泛型

Java:嵌套递归泛型,java,generics,Java,Generics,我有一组扩展一些基本实体的类。该集中的类也可以相互扩展,从而创建嵌套的层次结构 我的目标是让所有类都能访问一个方法,该方法可以创建它们自己的新实例。我想在我的基本实体中实现这个方法,以便所有扩展类都继承这个方法 下面是为我的模式定义的三个示例类: BaseEntity.java public abstract class BaseEntity<E extends BaseEntity> { Class<E> clazz; public BaseEnti

我有一组扩展一些基本实体的类。该集中的类也可以相互扩展,从而创建嵌套的层次结构

我的目标是让所有类都能访问一个方法,该方法可以创建它们自己的新实例。我想在我的基本实体中实现这个方法,以便所有扩展类都继承这个方法

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

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();
    }

}
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);
    }

}
public class Document extends Collection<Document> {

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

}
但是请注意,
Collection.java
的默认构造函数中存在编译器错误。我不确定这是为什么造成的,我认为这也是导致示例main方法中的编译器错误的原因。我做错了什么,如何解决

请注意,这是一个人为的例子,与我试图解决的一个更大的问题有关。我知道这个实现本身看起来很傻。

集合
是泛型类型,但您的
集合c
是原始类型。这意味着它的所有方法都将被视为原始类型,这意味着它们将返回对其中任何泛型的擦除

您的基类被声明为
BaseEntity
,这意味着在此方法中:

E getNewInstance()
删除是错误的

BaseEntity getNewInstance();
这意味着
c.getNewInstance()
返回一个
BaseEntity
,而不是一个
集合,这就是编译错误的原因

另一方面,
文档
不是泛型类。这意味着在编译时擦除并不重要(出于这些目的),
getNewInstance()
返回
E
表示的类型,在本例中为
Document
。同样地,
d.getNewInstance()
的返回类型为
Document
,因此该行可以很好地编译


顺便说一句:只要有递归泛型,就应该确保在递归中考虑泛型。例如,在这一行中:

BaseEntity<E extends BaseEntity>

这个构造函数的问题

public Collection() {
    super(Collection.class);
}
超类构造函数需要一个
,但类literal
集合。类
是一个
。这些类型是不兼容的,因为
E
可能是
集合
文档
,或者可能扩展
集合
的任何其他类型

任何像
Document
这样扩展
Collection
的类都必须提供自己的类,因此它将调用另一个
Collection
构造函数,该构造函数接受
类,因此我认为
Collection()
构造函数没有任何用处。我会移除它

另外,在
E
的上限中,您使用的正是试图使泛型的类的原始形式。使用

public abstract class BaseEntity<E extends BaseEntity<E>> {
文档本身不是泛型的,因此此代码仍然可以:

Document d = new Document();
d = d.getNewInstance();
文档
必须作为类型参数提供给
集合
,即使直接创建
文档
,因为
文档
集合

Collection cd=新文档();
cd=cd.getNewInstance();

与两个流行的java库类的名称冲突会导致混淆……完全有道理,解释得很好。我认为我的问题的一部分是我很难理解递归泛型
BaseEntity
是我很难理解的一个例子。但是我需要花更多的时间来理解,再次感谢。你能解释一下
BaseEntity
BaseEntity之间的区别吗?这比一个注释要大一点——这可能值得一个后续问题(我没有发现任何关于“带通配符的java递归泛型”的内容)。但是基本上不同之处在于泛型类本身在
E
上使用方法。考虑是否有一个方法,使用了<代码> e实体< />代码,并称为<代码>实体.GETNEVEN()/<代码>。使用
extensedbaseentity
,您将得到
E
。使用
extensedbaseentity
,您将返回一个
BaseEntity
。在这里,只需
BaseEntity
就没有必要执行
BaseEntity
。我理解主要方法中的差异。我仍然存在的一个问题是,即使在更改了类头之后,我的
集合
默认构造函数中仍然存在相同的编译器错误。我认为
集合
的默认构造函数是无用的。我建议删除它。当您必须寻找一个具体的子类时,
集合
有什么好处?此外,这将迫使您编写
Collection
,这将迫使
Collection
,以及无限多级别的泛型。
public abstract class BaseEntity<E extends BaseEntity<E>> {
public class Collection<E extends Collection<E>> extends BaseEntity<E> {
Collection<Document> c = new Collection<Document>(Document.class);
c = c.getNewInstance();
Document d = new Document();
d = d.getNewInstance();
Collection<Document> cd = new Document();
cd = cd.getNewInstance();