2

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]
} 
4

4 回答 4

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]
}

我猜你什么时候使用<?>它是自动限制的——真的不知道。

于 2012-11-24T20:52:02.320 回答
1

经过数小时的阅读和搜索,我终于找到了自己问题的答案。首先,我不得不说一下<?>,这里有一些信息。

那么各种集合的超类型是什么?它写成Collection <?>(读作“未知的集合”),即元素类型匹配任何东西的集合。(Java教程

好的,所以我们A<?>是各种As的超级类型。并且 parametrA<?>可以接受任何 As (多态)作为参数,因此第1行编译。 Java 教程

Java 规范告诉我们:

通配符是存在类型的受限形式。给定一个泛型类型声明G<T extends B>G<?>大致类似于 Some X<:BG<X>

B代表边界;X<:B表示子类型关系在类型 X 和 B 之间成立。

因此A<?>确实是自动限制的

当我们声明类型参数<S>时,在某种程度上,就好像我们声明了class S{},类型S与 Number(我们的绑定)没有任何关系并且强制转换为 1 会失败,所以我们应该声明“S 扩展 Number”为具有与 for 相同的效果<?>

于 2012-12-12T07:39:08.413 回答
0

?并且T是可以互换的(不是真的,因为你失去了确切的类型),因为没有界限。在这种情况下,K它有一个扩展的界限Number

因此,它abstract public <S extends Number> A<S> f(A<S> k);会做

于 2012-11-24T20:48:16.763 回答
0

这对我来说编译得很好:

abstract class A<K extends Number>
{
//  abstract public A<?> f(A<?> k); //[1] 
    abstract public A<K> f(A<K> k); 
} 
于 2012-11-24T20:50:50.417 回答