簡體   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