重载与泛型擦除

本文深入探讨了方法重载与泛型擦除之间的冲突,通过实例展示了如何在编译时避免错误,以及泛型擦除如何影响方法的识别与区分。着重解释了在Class文件中方法重载的特征签名不包含返回值,以及加入不同返回值的方法如何合法共存。最后提供了一个实际代码示例,清晰地说明了这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重载是面向对象语言重要的特性之一,判断重载可以根据参数列表的不同来决定是否两个方法是否存在重载。但返回值却不会成为判断因素之一,这是因为函数调用时并没有特征显示被调函数的返回值信息,也就无法区别被调用的是哪个函数。
泛型擦除是指任何泛型的参数变量在编译时,都会被擦除成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文件中的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值