重载是面向对象语言重要的特性之一,判断重载可以根据参数列表的不同来决定是否两个方法是否存在重载。但返回值却不会成为判断因素之一,这是因为函数调用时并没有特征显示被调函数的返回值信息,也就无法区别被调用的是哪个函数。
泛型擦除是指任何泛型的参数变量在编译时,都会被擦除成Object类,即List<Integer>与List<String>在编译时都被擦除成List<Object>。假如存在两个方法 void function(List<Integer>),void function(List<String>),按照重载定义,这两种方法的参数列表不同,是重载的。但泛型擦除的定义又告诉我们这两种方法是完全一样的,属于重定义。以下面例子为例:
上述代码在编译时会报错,Method method(ArrayList<Integer>) has the same erasure method(ArrayList<E>) as another method in type Clean
这是因为泛型擦除导致方法的特征一样,重定义。然而下面一段代码却可以通过编译,并运行
运行结果:
上述代码与前一段代码唯一的不同就是两个方法的返回值不同,这种情况与重载的定义冲突,之所以这次能编译和执行成功,是因为两个mehtod()方法加入了不同的返回值后才能共存在一个Class文件之中。Class文件方法表的数据结构时曾经提到过,方法重载要求方法具备不同的特征签名,返回值并不包含在方法的特征签名之中,所以返回值不参与重载选择,但是在Class文件格式之中,只要描述符不是完全一致的两个方法就可以共存。也就是说两个方法如果有相同的名称和特征签名,但返回值不同,那它们也是可以合法地共存于一个Class文件中的。
泛型擦除是指任何泛型的参数变量在编译时,都会被擦除成Object类,即List<Integer>与List<String>在编译时都被擦除成List<Object>。假如存在两个方法 void function(List<Integer>),void function(List<String>),按照重载定义,这两种方法的参数列表不同,是重载的。但泛型擦除的定义又告诉我们这两种方法是完全一样的,属于重定义。以下面例子为例:
public class Clean {
public void method(ArrayList<String> a) {
System.out.println("call method ArrayList<String>");
}
public void method(ArrayList<Integer> a) {
System.out.println("call method ArrayList<Integer>");
}
public static void main(String[] args) {
}
}
上述代码在编译时会报错,Method method(ArrayList<Integer>) has the same erasure method(ArrayList<E>) as another method in type Clean
这是因为泛型擦除导致方法的特征一样,重定义。然而下面一段代码却可以通过编译,并运行
public class Clean {
public String method(ArrayList<String> a) {
System.out.println("call method ArrayList<String>");
return "";
}
public int method(ArrayList<Integer> a) {
System.out.println("call method ArrayList<Integer>");
return 1;
}
public static void main(String[] args) {
Clean clean = new Clean();
clean.method(new ArrayList<Integer>());
clean.method(new ArrayList<String>());
}
}
运行结果:
call method ArrayList<Integer>
call method ArrayList<String>
上述代码与前一段代码唯一的不同就是两个方法的返回值不同,这种情况与重载的定义冲突,之所以这次能编译和执行成功,是因为两个mehtod()方法加入了不同的返回值后才能共存在一个Class文件之中。Class文件方法表的数据结构时曾经提到过,方法重载要求方法具备不同的特征签名,返回值并不包含在方法的特征签名之中,所以返回值不参与重载选择,但是在Class文件格式之中,只要描述符不是完全一致的两个方法就可以共存。也就是说两个方法如果有相同的名称和特征签名,但返回值不同,那它们也是可以合法地共存于一个Class文件中的。