所以,我的理解是下列哪项不工作,但为什么不工作?
interface Adapter<E> {}
class Adaptulator<I> {
<E, A extends I & Adapter<E>> void add(Class<E> extl, Class<A> intl) {
addAdapterFactory(new AdapterFactory<E, A>(extl, intl));
}
}
该add()
方法给我一个编译错误,“当第一个绑定是类型参数时,不能指定任何其他绑定Adapter <E>”(在Eclipse中),或“在类型参数后不能跟其他边界”(在IDEA中),请选择。
显然,你只是不允许使用类型参数I
出现,之前的&
,就是这样。(在您问之前,如果您切换它们,那I
是行不通的,因为不能保证这不是具体的课程。)但是为什么不呢?我已经查看了Angelika Langer的常见问题解答,但找不到答案。
通常,当某些泛型限制似乎是任意的时,这是因为您造成了类型系统实际上无法强制正确性的情况。但是我看不出什么情况会破坏我在这里试图做的事情。我想说这可能与类型擦除后的方法分派有关,但是只有一种add()
方法,所以这并不意味着有任何歧义。
有人可以为我演示问题吗?
我也不确定为什么会有限制。您可以尝试向Java 5 Generics(主要是Gilad Bracha和Neal Gafter)的设计者发送友好的电子邮件。
我的猜测是,他们只想支持绝对最小的交集类型(本质上就是多个边界),以使语言不会比需要的复杂。相交不能用作类型注释;程序员仅在交集出现为类型变量的上限时才可以表达交集。
为何甚至支持这种情况?答案是,多个范围允许您控制擦除,这可以在生成现有类时保持二进制兼容性。正如Naftalin和Wadler 在该书的第17.4节中所解释的那样,一种max
方法在逻辑上将具有以下签名:
public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll)
但是,这将擦除:
public static Comparable max(Collection coll)
与的历史签名不匹配max
,并导致旧客户端中断。如果有多个边界,则仅考虑最左边的边界以进行擦除,因此如果max
给出以下签名:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
然后其签名的擦除变为:
public static Object max(Collection coll)
等于max
前泛型的签名。
Java设计人员只关心这种简单情况并限制了交集类型的其他(更高级的)用法似乎是合理的,因为他们只是不确定它可能带来的复杂性。因此,做出此设计决策的原因不必一定是可能的安全问题(正如该问题所暗示的)。
在即将发布的OOPSLA论文中,将更多地讨论交集类型和泛型的限制。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句