关于《Java泛型与集合》中类型擦除下方法重载规则的问询
泛型重载规则的核心含义
先给你把这个规则讲透:Java的泛型是基于类型擦除实现的——编译完成后,所有泛型类型都会被擦除成对应的原始类型(比如List<Integer>擦除后是List,Map<String, Integer>擦除后是Map)。
所以重载方法时,不仅不能有完全相同的方法签名,也不能有类型擦除后签名完全一致的两个不同方法。因为编译后JVM无法区分这两个方法,会直接抛出编译错误,本质上和“不能定义两个签名完全相同的方法”是同一个逻辑——JVM找不到正确的方法去调用。
举个反例你就懂了:如果你写了下面两个方法,编译器直接报错:
// 第一个方法:处理Integer列表 public static int sum(List<Integer> ints) { /* ... */ } // 第二个方法:处理String列表——擦除后签名是sum(List),和上面完全一致,编译报错! public static String sum(List<String> strings) { /* ... */ }
补全后的完整示例代码
原示例里的第一个方法是处理List<Integer>的求和,我们需要补充擦除后签名不同的重载方法,比如处理int数组、Set<Long>等,这样就能合法重载了:
import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.Arrays; class Overload { // 处理List<Integer>的求和方法,擦除后签名:sum(List) public static int sum(List<Integer> ints) { int sum = 0; for (int i : ints) { sum += i; } return sum; } // 处理int数组的求和方法,擦除后签名:sum(int[]),和上面的签名完全不同 public static int sum(int[] intArray) { int sum = 0; for (int num : intArray) { sum += num; } return sum; } // 处理Set<Long>的求和方法,擦除后签名:sum(Set),和前两个都不一样 public static long sum(Set<Long> longs) { long sum = 0; for (long num : longs) { sum += num; } return sum; } // 测试主方法 public static void main(String[] args) { List<Integer> intList = Arrays.asList(1, 2, 3); System.out.println("List<Integer>求和结果:" + sum(intList)); // 输出6 int[] intArray = {4, 5, 6}; System.out.println("int数组求和结果:" + sum(intArray)); // 输出15 Set<Long> longSet = new HashSet<>(Arrays.asList(7L, 8L, 9L)); System.out.println("Set<Long>求和结果:" + sum(longSet)); // 输出24 } }
这个示例里的三个sum方法,擦除后的签名分别是sum(List)、sum(int[])、sum(Set),彼此都不重复,所以编译器和JVM都能正常识别,完美符合重载规则。
内容的提问来源于stack exchange,提问作者grustamli
相关产品推荐
相关产品推荐

