为什么我不能在具有多个边界的类型参数中使用类型参数? [英] Why can't I use a type argument in a type parameter with multiple bounds?

查看:32
本文介绍了为什么我不能在具有多个边界的类型参数中使用类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我知道以下内容不起作用,但是为什么不起作用?

So, I understand that the following doesn't work, but why doesn't it work?

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() 方法给我一个编译错误,当第一个绑定是一个类型参数时,不能指定任何额外的绑定适配器<E>"(在 Eclipse 中),或者类型参数不能是其次是其他边界"(在 IDEA 中),请选择.

The add() method gives me a compile error, "Cannot specify any additional bound Adapter<E> when first bound is a type parameter" (in Eclipse), or "Type parameter cannot be followed by other bounds" (in IDEA), take your pick.

很明显,您只是不允许在 & 之前使用类型参数 I,仅此而已.(在你问之前,如果你切换它们是行不通的,因为不能保证 I 不是一个具体的类.)但为什么不呢?我已经浏览了 Angelika Langer 的常见问题解答,但找不到答案.

Clearly you're just Not Allowed to use the type parameter I there, before the &, and that's that. (And before you ask, it doesn't work if you switch 'em, because there's no guarantee that I isn't a concrete class.) But why not? I've looked through Angelika Langer's FAQ and can't find an answer.

通常,当某些泛型限制看起来很随意时,那是因为您创造了一种类型系统实际上无法强制执行正确性的情况.但我不知道什么情况会破坏我在这里尝试做的事情.我想说这可能与类型擦除后的方法调度有关,但是只有一个 add() 方法,所以它不像有任何歧义......

Generally when some generics limitation seems arbitrary, it's because you've created a situation where the type system can't actually enforce correctness. But I don't see what case would break what I'm trying to do here. I'd say maybe it has something to do with method dispatch after type erasure, but there's only one add() method, so it's not like there's any ambiguity...

有人可以为我演示这个问题吗?

Can someone demonstrate the problem for me?

推荐答案

我也不知道为什么会有这个限制.您可以尝试向 Java 5 泛型的设计者(主要是 Gilad Bracha 和 Neal Gafter)发送一封友好的电子邮件.

I'm also not sure why the restriction is there. You could try sending a friendly e-mail to the designers of Java 5 Generics (chiefly Gilad Bracha and Neal Gafter).

我的猜测是他们只想支持绝对最少的 交叉类型(本质上就是多重边界),使语言不会比需要的更复杂.交集不能用作类型注释;程序员只有当它出现在类型变量的上界时才能表达交集.

My guess is that they wanted to support only an absolute minimum of intersection types (which is what multiple bounds essentially are), to make the language no more complex than needed. An intersection cannot be used as a type annotation; a programmer can only express an intersection when it appears as the upper bound of a type variable.

为什么甚至支持这种情况?答案是多个边界允许您控制擦除,这允许在生成现有类时保持二进制兼容性.正如 Naftalin 和 Wadler 所著的 book 的第 17.4 节所述,max 方法在逻辑上具有以下签名:

And why was this case even supported? The answer is that multiple bounds allow you to control the erasure, which allows to maintain binary compatibility when generifying existing classes. As explained in section 17.4 of the book by Naftalin and Wadler, a max method would logically have the following signature:

public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll)

然而,这会擦除:

public static Comparable max(Collection coll)

max的历史签名不匹配,导致旧客户端崩溃.对于多个边界,只考虑最左边的边界进行擦除,因此如果给 max 提供以下签名:

Which does not match the historical signature of max, and causes old clients to break. With multiple bounds, only the left-most bound is considered for the erasure, so if max is given the following signature:

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

然后擦除其签名变成:

public static Object max(Collection coll)

它等于泛型之前max的签名.

Which is equal to the signature of max before Generics.

Java 设计者只关心这种简单的情况并限制其他(更高级的)交叉类型的使用似乎是合理的,因为他们只是不确定它可能带来的复杂性.所以这个设计决定的原因不一定是可能的安全问题(正如问题所暗示的那样).

It seems plausible that the Java designers only cared about this simple case and restricted other (more advanced) uses of intersection types because they were just unsure of the complexity that it might bring. So the reason for this design decision does not need to be a possible safety problem (as the question suggests).

即将发表的 OOPSLA 论文中更多地讨论了泛型的交叉类型和限制.

这篇关于为什么我不能在具有多个边界的类型参数中使用类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆