这是一个代码段
public class HelloWorld{
public static void main(String[] args) {
GenericClass<Integer> test = new GenericClass<Integer>();
test.method(new ArrayList<Integer> ());
}
}
class GenericClass<T> {
public void overloadedMethod( Collection<?> o) {
System.out.println("overloadedMethod(Collection<?>)");
}
public void overloadedMethod( List<Number> s) {
System.out.println("overloadedMethod(List<Number>)");
}
public void overloadedMethod( ArrayList<Integer> i) {
System.out.println("overloadedMethod(ArrayList<Integer>)");
}
public void method(List<T> t) {
overloadedMethod(t) ; // which method is called?
}
}
Run Code Online (Sandbox Code Playgroud)
我期待它会使用Arraylist参数调用重载方法,但是为什么会调用Collection?
这个确切的代码用于Angelika Langer关于java泛型的网页中的一个例子
如果页面出现故障,我会发布解释:
程序打印:
overloadedMethod(系列)
有人可能会预期会调用ArrayList的版本,但这又是错误的期望.让我们看看编译器将泛型类转换为什么.
示例(在类型擦除之后):
public final class GenericClass {
private void overloadedMethod( Collection o) {
System.out.println("overloadedMethod(Collection<?>)");
}
private void overloadedMethod( List s) {
System.out.println("overloadedMethod(List<Number>)");
}
private void overloadedMethod( ArrayList i) {
System.out.println("overloadedMethod(ArrayList<Integer>)");
}
private void method(List t) {
overloadedMethod(t) ;
}
public static void main(String[] args) {
GenericClass test = new GenericClass();
test.method(new ArrayList ());
}
}
Run Code Online (Sandbox Code Playgroud)
有人可能错误地认为编译器会决定重载方法的List版本是最佳匹配.但这当然是错的.重载方法的List版本最初是一个以List作为参数的版本,但在调用时会传递List,其中T可以是任何类型,不必是Number.由于T可以是任何类型,因此重载方法的唯一可行版本是Collection的版本.
实际上,如果注释掉Collection方法,则会出现编译器错误,因为List和ArrayList太具体,不适合所有可能的<T>类型.
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |