当泛型遇见重载


import java.util.List;

public class TestFanXing {

	public static void method(List<String> list) {
		System.out.println("method(List<String> list)");
	}
	
	public static void method(List<Integer> list) {
		System.out.println("method(List<Integer> list)");
	}

}

编译不通过,因为泛型只是语法糖,参数List<String> list和List<Integer> list编译之后都被擦除了,变成了一样的原生类型List<E>,擦除动作导致这两种方法的特征签名变得一模一样。

以下代码需jdk1.6

import java.util.ArrayList;
import java.util.List;

public class TestFanXing {

	public static String method(List<String> list) {
		System.out.println("method(List<String> list)");
		return "";
	}
	
	public static int method(List<Integer> list) {
		System.out.println("method(List<Integer> list)");
		return 1;
	}
	public static void main(String[] args) {
		method(new ArrayList<String>());
		method(new ArrayList<Integer>());
	}

}
运行结果:
method(List<String> list)
method(List<Integer> list)

可见运行成功了。但是不代表返回值不同就可以重载。


注:在《java虚拟机规范(第2版)》中,分别定义了字节码层面的方法特征签名,以及java代码层面的方法特征签名,特征签名最重要的任务就是作为方法独一无二且不可重复的ID,在java代码中的方法特征签名只包括了方法名称、参数顺序及参数类型,而在字节码中的特征签名还包括方法返回值及受查异常表。

重载当然不是根据返回值来确定的,这次之所以可以编译并执行成功,是因为两个method方法加入了不同的返回值后才能共存在一个Class文件之中。而方法重载要求方法具备不同的特征签名,返回值并不包含在方法的特征签名中,所以返回值不参与重载选择,但是在Class文件格式中,特征签名的范围更大一些,只要描述符(作用是描述方法的参数列表和返回值)不是完全一致的两个方法就可以共存。也就是说,两个方法如果有相同的名称和特征签名,但返回值不同,那它们也是可以合法地共存在一个Class文件中的。






猜你喜欢

转载自blog.csdn.net/dear_mango/article/details/80668972
今日推荐