[英]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
的类并将它们命名为EBE1
和EBE2
。
现在,您使用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.