Java 教程就是这么说的,<?>
而且<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]
}
您必须限制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]
}
我猜你什么时候使用<?>
它是自动限制的——真的不知道。
经过数小时的阅读和搜索,我终于找到了自己问题的答案。首先,我不得不说一下<?>
,这里有一些信息。
那么各种集合的超类型是什么?它写成Collection
<?>
(读作“未知的集合”),即元素类型匹配任何东西的集合。(Java教程)
好的,所以我们A<?>
是各种As的超级类型。并且 parametrA<?>
可以接受任何 As (多态)作为参数,因此第1行编译。
Java 规范告诉我们:
通配符是存在类型的受限形式。给定一个泛型类型声明
G<T extends B>
,G<?>
大致类似于 SomeX<:B
。G<X>
B代表边界;X<:B
表示子类型关系在类型 X 和 B 之间成立。
因此A<?>
确实是自动限制的;
当我们声明类型参数<S>
时,在某种程度上,就好像我们声明了class S{}
,类型S与 Number(我们的绑定)没有任何关系并且强制转换为 1 会失败,所以我们应该声明“S 扩展 Number”为具有与 for 相同的效果<?>
。
?
并且T
是可以互换的(不是真的,因为你失去了确切的类型),因为没有界限。在这种情况下,K
它有一个扩展的界限Number
因此,它abstract public <S extends Number> A<S> f(A<S> k);
会做
这对我来说编译得很好:
abstract class A<K extends Number>
{
// abstract public A<?> f(A<?> k); //[1]
abstract public A<K> f(A<K> k);
}