Java泛型:方法声明参数中的类型扩展

时间:2014-02-27 20:25:33

标签: java generics wildcard

我正在学习Java Generics。我的理解是Generics按类型参数化集合。在Oracle教程中,有以下注释:

  

在通用代码中,问号(?),称为通配符,   代表一种未知的类型。

在下一页上,下面是参数中带有上限通配符的方法声明示例:

public void process(List<? extends Foo> list)

鉴于此,我想知道为什么这种方法声明是非法的:

public void process(List<E extends Number> list)

虽然这是合法的:

public <E extends Number> void process(List<E> list)

4 个答案:

答案 0 :(得分:5)

指定方法parm类型时,您使用的是泛型类型,因此必须事先定义它。在本声明中,您使用的是没有定义的E

public void process(List<E extends Number> list) { /* ... */ }

但是,在第二个中,它是在方法返回类型(void)之前定义的:

public <E extends Number> void process(List<E> list) { /* ... */ }

答案 1 :(得分:3)

没有比“因为语言的设计方式更好”的答案。但是考虑它的一种方法是类型参数被视为方法的另一个参数列表:它们必须一次出现在一个(有序)列表中。

您可以通过显式传递类型参数来调用泛型方法:例如,foo.<Integer, String>process(list)。这意味着类型参数必须具有明确的顺序,就像普通的值参数一样。

答案 2 :(得分:2)

完成@ phoenix的回答,这句话中的问题

public void process(List<E extends Number> list) { /* ... */ }

是你的通用类型E的声明是在错误的地方。正确的位置在返回类型之前:

public <E extends Number> void process(List<E> list) { /* ... */ }

但是,另一个定义泛型类型的可能位置是类声明本身:

class MyClass<E extends Number> {

    public void process(List<E> list) { /* ... */ }

}

答案 3 :(得分:0)

大约两者都相同,但我只使用第一个。