簡體   English   中英

使用自引用類型時java泛型方法中的綁定不匹配錯誤

[英]bound mismatch error in java generic method when using self-referring type

在泛型方法中使用自引用類型時出現綁定不匹配錯誤,但不是在泛型類聲明中; 這是錯誤代碼的示例:

public class Container {
   public static class User<X> {}  // line 1
   public static class Box<U extends User<Box<U>>> {} // line 2
   public static class NiceBox<U extends User<Box<U>>> {}   // line 3: OK
   <U extends User<Box<U>>> void niceMethod(U user) {}   // line 4: NOT OK
}

編譯第 4 行的錯誤消息:綁定不匹配:類型U不是類型Container.Box<U>的有界參數< U extends Container.User<Container.Box<U>>>的有效替代品

我不明白為什么,在此先感謝您的幫助,SC

PS:請注意,與之前提出的問題不同,這里提出的問題僅存在於泛型方法中,編譯器在泛型類聲明中使用時接受有問題的類型綁定。

我正在使用最新的 Eclipse 發行版附帶的 Java 11 編譯器。

以下是有關我要實現的目標的更多詳細信息。 我正在構建一個需要在類型 C 的上下文中對類型 T 的目標執行一些工作的 Box,其中該上下文 C 必須滿足最小接口。 然后我需要定義處理 Box 的方法(因此需要一個具有自引用類型綁定的通用方法)。 這是代碼:

static class Box<T,C extends MinimalContext<Box<T,C>>> {
    void doSomething(T target, C context) {
        // do something
    }
}

interface MinimalContext<B> {   
    boolean validate(B box);
    void print(B box);
}

// FAILS:
<T,C extends MinimalContext<Box<T,C>>>
void processBox(Box<T,C> box) {}   

// Instead use:
class BoxProcessor<T,C extends MinimalContext<Box<T,C>>>    
{
    BoxProcessor(Box<T,C> box) {
        // use box as niceMethod would do 
    }
}

請注意,由於限制只存在於泛型方法而不是類,我使用內部類來完成泛型方法的工作......還有其他解決方案嗎?

來自 eclipse 開發人員的人可以多說一些有關此限制的信息嗎?

這似乎是 Eclipse 編譯器的限制或更高級別的嚴格性。 javac可以很好地接受該代碼。

在 Eclipse 中,您可以編寫:

public static class User<T> {}
public static class Box<T extends User<Box<T>>> {}
<T extends User<Box<?>>> void niceMethod(T user) {}

然后你可以聲明一個類:

static class UserBox extends User<Box<?>> {}

Eclipse 將允許您:

public static void main(String[] args)
{
    Container c = new Container();

    c.niceMethod(new UserBox());
}

但是它不會讓你創建一個具體的Box 例如:

Box<UserBox> b = new Box<>();

Eclipse 不允許,但javac允許。

我懷疑 Eclipse 可能正在做正確的事情,因為您在說:

Box接受一個類的類型參數,該類使用Box的類型參數擴展User ,該類型參數具有我們正在擴展的類型的類型參數。 這對我來說聽起來不可能,但我可能會遺漏一些東西。

編輯(因為問題已更新以顯示界面):

與其將接口定義為完全通用並嘗試限制Box定義中的上下文類型,不如定義一個更具限制性的接口,例如:

interface BoxContext<B extends Box<?, ?>> {
    boolean validate(B box);
    void print(B box);
}

然后,您可以從Box的定義中刪除自引用泛型:

static class Box<T, C extends BoxContext<?>> {
    void doSomething(T target, C context) {
        // do something
    }
}

然后允許您定義您的方法:

<T, C extends BoxContext<?>> void processBox(Box<T, C> box) {}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM