所以,我了解以下行不通,但为什么行不通?
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()
方法给我一个编译错误,“当第一次绑定(bind)是类型参数时,不能指定任何额外的绑定(bind)适配器
显然,您只是不允许在 &
之前使用类型参数 I
,仅此而已。 (在你问之前,如果你切换它们是行不通的,因为不能保证 I
不是一个具体的类。)但为什么不呢?我浏览了 Angelika Langer 的常见问题解答,但找不到答案。
通常,当某些泛型限制看起来很随意时,这是因为您创建了类型系统实际上无法强制正确性的情况。但我不知道什么情况会破坏我在这里尝试做的事情。我会说也许它与类型删除后的方法调度有关,但是只有一个 add()
方法,所以它不像有任何歧义......
有人可以为我演示一下这个问题吗?
最佳答案
我也不确定为什么会有限制。您可以尝试向 Java 5 泛型的设计者(主要是 Gilad Bracha 和 Neal Gafter)发送一封友好的电子邮件。
我的猜测是他们只想支持绝对最小值 intersection types (本质上就是多重边界),使语言不比需要的复杂。交集不能用作类型注解;只有当交集作为类型变量的上界出现时,程序员才能表达交集。
为什么甚至支持这种情况?答案是多个边界允许您控制删除,这允许在生成现有类时保持二进制兼容性。如 book 的第 17.4 节所述根据 Naftalin 和 Wadler,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
在Generics之前的签名。
Java 设计人员只关心这种简单的情况并限制交集类型的其他(更高级)使用似乎是合理的,因为他们只是不确定它可能带来的复杂性。所以这个设计决定的原因不一定是一个可能的安全问题(正如问题所暗示的那样)。
在 upcoming OOPSLA paper 中更多关于泛型的交集类型和限制的讨论.
关于java - 为什么我不能在具有多个边界的类型参数中使用类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/197190/