[英]Type erasure in Java
我必须处理嵌套的集合(例如,列表列表或地图列表),这就是我要处理的方式:
public static String doSomething(Map<?, ? extends Collection<?>> map) {
...
}
public static String doSomething(Map<?, ? extends Map<?, ?>> map) {
...
}
但是编译器告诉我,以上两种方法具有相同的类型擦除。 我不知道为什么,因为我指定了不同的类型界限。
删除Map<?, ? extends Collection<?>>
Map<?, ? extends Collection<?>>
是Map<Object, Object>
删除Map<?, ? extends Map<?, ?>>
Map<?, ? extends Map<?, ?>>
也是Map<Object, Object>
要了解原因,您需要了解如何计算Map
的删除量。 基本上,您采用类型( Map<K, V>
)并将形式类型参数(而不是实际类型参数)替换为其各自的最小上限类型。 在这种情况下,最小的上限类型是K
和V
Object
,因为在Map
接口中它们都没有任何类型约束。
我想我可能已经编造了“最小上限类型”一词。 (对不起)但是我的意思是最具体的类型,它不是集合中允许的任何可能类型的子类型。
考虑擦除的另一种方法如下。 考虑此类:
public class Test <T> {
public set(T t):
}
现在想象一下,我们必须不使用泛型来表达这一点。 我们将使用什么实际类型代替T
? 在这种情况下,它将是Object
。
而事实上,当一个泛型类型映射到运行时类型,这正是发生了什么!
但是,基本上,您将无法创建仅在Map
类型的类型参数化方面不同的方法重载。 除非您更改类型:
public class X implements Map<String, Integer> ...
public class Y implements Map<String, Double> ...
public static String doSomething(X map) {
...
}
public static String doSomething(Y map) {
...
}
....至少可以说很难看。
解决方案:使用不同的方法名称,而不要尝试重载相同的名称。
无法重载每个重载的形式参数类型都擦除为相同原始类型的方法。
在您的代码中,两个方法在类型擦除后具有相同的签名:
public static String doSomething(Map map);
要解决您的问题,您可以仅使用两个不同的方法名称,而不必重载该方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.