[英]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.