Java tutorial说<?>
和<T>
可以互换。为什么我可以在下面编译行1,而我无法编译行[2]?
abstract class A<K extends Number>{
abstract public A<?> f(A<?> k); //[1]
abstract public <S> A<S> f(A<S> k); //[2]
}
答案 0 :(得分:3)
您必须限制S
扩展Number
:
abstract class A<K extends Number>{
//abstract public A<?> f(A<?> k); //[1]
abstract public <S extends Number> A<S> f(A<S> k); //[2]
}
我猜你使用<?>
时它是自动限制的 - 真的不知道。
答案 1 :(得分:1)
经过几个小时的阅读和搜索,我终于找到了自己问题的答案。
首先,我不得不说<?>
,这里有一些信息。
那么各种收藏品的超类型是什么?它是写的 集合
<?>
(发音为“未知集合”),即a 元素类型与任何东西匹配的集合。(Java tutorials)
好的,所以我们的A<?>
是超强类型的所有种类的As。
并且parametr A<?>
可以接受任何As(多态)作为参数,因此行1编译。
Java规范告诉我们:
通配符是存在类型的受限形式。鉴于一般 类型声明
G<T extends B>
,G<?>
大致类似 某些X<:B
。G<X>
B 代表界限; X<:B
表示子类型关系在两者之间
类型X和B.
因此A<?>
确实是自动限制;
当我们声明类型参数<S>
时,它在某种程度上就像我们声明class S{}
一样,类型 S 与Number没有任何关系(我们的绑定)并转换为一个会失败,所以我们应该声明“S extends Number”以产生与<?>
相同的效果。
答案 2 :(得分:0)
?
和T
是可以互换的(不是真的,因为你正在丢失确切的类型),因为没有界限。
在这种情况下,K
具有扩展Number
因此,abstract public <S extends Number> A<S> f(A<S> k);
将会执行
答案 3 :(得分:0)
这对我来说很好:
abstract class A<K extends Number>
{
// abstract public A<?> f(A<?> k); //[1]
abstract public A<K> f(A<K> k);
}