繁体   English   中英

Java 不允许用泛型调用递归方法?

[英]Java not allowed to call recursive method with generic type?

public class ResourceAssembler<T extends BasedEntity> {


    public Resource<T> toResource(T  entity) {
       ExtendsBasedEntity e = getExtendsBasedEntity();
       toResource(e); //<----compile error
       //some other code
    }
}

public class ExtendsBasedEntity extends BasedEntity{}

但是,如果您从外部调用它,那很好

//some other class
new ResourceAssembler<ExtendsBasedEntity>().toResource(new ExtendsBasedEntity())

为什么?

Error:(28, 25) java: incompatible types: spring.BasedEntity cannot be converted to T

T可能不是ExtendsBasedEntity ,而是BaseEntity的其他一些子类型,因此会出现编译错误。

“解决”问题的一种方法是使用类型标记

public class ResourceAssembler<T extends BasedEntity> {

    private final Class<T> type;

    public ResourceAssembler(Class<T> type) {
        this.type = type;
    }

    public Resource<T> toResource(T  entity) {
       toResource(type.newInstance());
       //some other code
    }
}

假设这对你有用。

让我们创建两个扩展BasedEntity的类并将它们命名为EBE1EBE2
现在,您使用EBE1作为类型参数创建ResourceAssembly object。 但是假设在toResource方法的实现中,您执行了类似return toResource(new EBE2()); .

所以toResource()的返回类型变成了Resource<EBE2>但这是错误的,因为根据结构你应该返回Resource<EBE1> 这就是编译时错误的原因。 Java 的类型安全本能开始发挥作用。

如果您想为toResource方法返回一个泛型,那么您要么必须按原样传递entity object,要么将其更改为您正在初始化它的具体类型而不使用泛型(尽管我不知道为什么有人会使用第二个选项,但它是使其“编译”的“解决方案”)。

此外,在您声明它时在外面。 您没有为ResourceAssembly指定类型参数,因此它是原始参数。 尝试使用类型参数来完成。 你也会有红色的波浪线。

这是一个例子:

static class Resource<T> {

}

static class BasedEntity {

}

static class ExtendsBasedEntity1 extends BasedEntity {

}

static class ExtendsBasedEntity2 extends BasedEntity {

}
static public class ResourceAssembler<T extends BasedEntity> {


    public Resource<T> toResource(T entity) {
        return toResource(new ExtendsBasedEntity1()); //<----compile error
    }
}  



    public static void main(String[] args) {
        new ResourceAssembler<ExtendsBasedEntity1>().toResource(new ExtendsBasedEntity1()); // <---- No errors or warnings. This is valid and legal
        new ResourceAssembler<ExtendsBasedEntity2>().toResource(new ExtendsBasedEntity1()); // <----- red squiggly lines here
        new ResourceAssembler().toResource(new ExtendsBasedEntity2()); // <--compiler warning about raw types but no error
    }  

如果您无论如何需要使其按您希望的方式工作,那么不要返回Resource<T> ,而是返回Resource<ExtendsBasedEntity>因为您在泛型方法中递归并且看起来您需要一个具体类型的 object 到 go作为递归调用的参数。 所以这样做是有道理的。
或者,go 使用@Bohemian的方法,并确保在您使用的类型的 class 声明中,有一个无参数构造函数,否则您将拥有InstantiationException

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM