Java中的高级多态性
我在大学里有高级编程课程,我在理解这些代码的工作原理方面有点困难Java中的高级多态性,java,generics,polymorphism,parametric-polymorphism,Java,Generics,Polymorphism,Parametric Polymorphism,我在大学里有高级编程课程,我在理解这些代码的工作原理方面有点困难 public final class GenericClass<T> { private void overloadedMethod(Collection<?> o) { System.out.println("Collection<?>"); } private void overloadedMethod(List<Number> o) {
public final class GenericClass<T> {
private void overloadedMethod(Collection<?> o) {
System.out.println("Collection<?>");
}
private void overloadedMethod(List<Number> o) {
System.out.println("List<Number>");
}
private void overloadedMethod(ArrayList<Integer> o) {
System.out.println("ArrayList<Integer>");
}
public void method(List<T> l) {
overloadedMethod(l);
}
public static void main(String[] args) {
GenericClass<Integer> test = new GenericClass<Integer>();
test.method(new ArrayList<Integer>());
}
}
公共最终类GenericClass{
私有void重载方法(集合o){
系统输出打印项次(“收集”);
}
私有void重载方法(列表o){
系统输出打印项次(“列表”);
}
私有void重载方法(ArrayList o){
System.out.println(“ArrayList”);
}
公共作废方法(列表l){
超载法(l);
}
公共静态void main(字符串[]args){
GenericClass测试=新的GenericClass();
测试方法(新ArrayList());
}
}
为什么此代码打印“集合”?方法(列表l)的声明没有指定类型T的任何边界。不能保证T是数字或数字的子类。因此,编译器只能决定此方法调用
重载方法(集合o)
请记住:编译后,类文件中不再提供有关泛型的信息。无论何时定义泛型类型,都会自动提供相应的原始类型 这种方法
public void method(List<T> l) {
}
公共作废方法(列表l){
}
正在替换为
public void method(List<Object> l) {
}
公共作废方法(列表l){
}
如果您阅读了通配符类型,您将看到List
和List
或者
ArrayList
和List
没有任何类型关系<代码>列表是集合
的一个子类型,因此调用此方法。当处理方法重载时,必须牢记三个概念:
test.method(new ArrayList());
编译器发现ArrayList()
可以扩展到Collection
,因为它具有最高优先级,所以调用这些版本而忽略其他版本
注意:如果您将其他两个方法的声明更改为
private void overloadedMethod(ArrayList o)
和private void overloadedMethod(List o)
编译器也将调用集合
版本,因为它是首选的版本谢谢,您的答案甚至解释了更改overloadedMethod后的原因(列表o)
到重载方法(列表o)
程序打印出列表
而不是集合
最重要的是你的最后一句话。这解释了一切!回答得很好,但是-1提醒你注意一个事实,声明GenericClass
反而会导致对overloadedMethod(集合)的相同调用
。所以这里还发生了一些事情。提示:只有当您更改为重载方法(ListNo)时,它才会起作用。如果private void重载方法(List o){//则将通过集合调用Listmethod。“@Java Player:我也一直在办公室访问这个论坛,并不断更新我自己。顺便说一句,你尝试过吗?如果你尝试过,请在这里给出结论。-1对不起,这是错误的。在指定的更改中,它将调用重载方法(列表)
(它不会调用重载方法(ArrayList)
因为方法
需要一个列表
。实际上,这里的推理不足以回答这个问题。编译器决定调用哪个方法重载,在类型擦除之前发生。