繁体   English   中英

Java嵌套自引用泛型

[英]Java nested self referential generic

我有一个类,它有一个自引用泛型参数和一个具有相同超类的参数。 静态函数与类具有相同的边界。

public class Bar<T extends Bar<T, C>, C extends Bar<C, ?>> {

    Bar() {
        foo((T) null);
        foo((C) null);//compile error
    }

    static <S_T extends Bar<S_T, S_C>, S_C extends Bar<S_C, ?>> void foo(S_T t) {
    }
}

这会产生以下错误。

绑定不匹配:Bar <T,C>类型的泛型方法foo(S_T)不适用于参数(C)。 推断的类型C不是有界参数<S_T extends Bar <S_T,S_C >>的有效替代

我无法弄清楚为什么C不能传入foo()因为CBar<C,?>而且通配符是一个Bar因为声明中的第二个参数表示它扩展了Bar。

我知道这可能是一个坏主意,并产生难以理解的代码,但我真的想知道为什么这不编译。

简短的回答是Java类型推断实际上非常蹩脚。

Java没有对通配符执行任何智能推理? Bar的声明中推断它在逻辑上受Bar< ?, ? > Bar< ?, ? > (也不是那个界限中的?本身是有界的,等等)。 一旦你把? 这本身就是Java所知道的。 虽然没有什么可以阻止你在Bar的声明中将这个限制放在通配符上,但即使这对Java没有帮助; Java会不会假设两个独立的? s指的是同一类型,即使更深入的分析意味着必须这样做。 换句话说,即使使用以下代码,编译错误仍然存​​在:

public class Bar<T extends Bar<T, C>, C extends Bar<C, ? extends Bar<?, ? extends Bar<?, ?>>>> {

    Bar() {
        foo((T) null);
        foo((C) null);//compile error
    }

    static <S_T extends Bar<S_T, S_C>, S_C extends Bar<S_C, ? extends Bar<?, ? extends Bar<?, ?>>>> void foo(S_T t) {
    }
}

我不是泛型的破解,但我认为问题是你声明foo()的类型是

<S_T extends Bar<S_T,S_C> > void foo(S_T)

然后在两个不同的上下文中调用它,这些上下文需要foo()的不同静态类型。

在第一个上下文中, S_T具有类型T而在第二个上下文中,它具有类型C 但是TC被声明为Bar<T,?>Bar<C,?> ,它们是静态不兼容的类型。 我猜想编译器在第一次调用中计算出foo()的类型,然后正确地假设,类型必须始终保持相同,而不是。

暂无
暂无

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

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