Java: nested recursive generics

I have a set of classes that extend some basic entities Classes in this collection can also extend each other to create a nested hierarchy

My goal is to make all classes have access to the methods that create their own new instances I want to implement this method in my base entity so that all extension classes inherit this method

Here are three sample classes defined for my schema:

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

}

With this setting, I hope to achieve such things:

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

Note, however, that collection There is a compiler error in the default constructor of Java I'm not sure why this is the case. I think it will also lead to compiler errors in the example main method What did I do wrong and how to solve this problem?

Please note that this is a human example of a larger problem I am trying to solve I know the implementation itself looks silly

Solution

Collection and lt, e... > are generic types, but your collection C is the original type This means that all its methods will be treated as primitive types, which means that they will return any generic type

Your base class is declared as baseentity < e extends baseentity >, which means that in this method:

E getNewInstance()

Erase yes

BaseEntity getNewInstance();

This means that c.getnewinstance () returns a baseentity instead of a collection, which is the source of compilation errors

Documentation, on the other hand, is not a generic class This means that erasure does not matter at compile time (for these purposes), and getnewinstance () returns the type represented by E, in this case document Therefore, the return type of d.getnewinstance () is document, so this line compiles normally

By the way: whenever you have recursive generics, you should ensure that generics are considered in recursion For example, in this line:

BaseEntity<E extends BaseEntity>

You have defined baseentity as a generic class – but then immediately ignore its generics in the e extension baseentity That line should be:

BaseEntity<E extends BaseEntity<E>>
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>