[英]Type erasure in Java
I had to process nested collections (for example, a map of lists or a map of maps) and that is the way I was going to handle it: 我必须处理嵌套的集合(例如,列表列表或地图列表),这就是我要处理的方式:
public static String doSomething(Map<?, ? extends Collection<?>> map) {
...
}
public static String doSomething(Map<?, ? extends Map<?, ?>> map) {
...
}
But I am told by the compiler that the above two methods have the same type erasure. 但是编译器告诉我,以上两种方法具有相同的类型擦除。 I wonder why, since I have specified different type bounds.
我不知道为什么,因为我指定了不同的类型界限。
The erasure of Map<?, ? extends Collection<?>>
删除
Map<?, ? extends Collection<?>>
Map<?, ? extends Collection<?>>
is Map<Object, Object>
Map<?, ? extends Collection<?>>
是Map<Object, Object>
The erasure of Map<?, ? extends Map<?, ?>>
删除
Map<?, ? extends Map<?, ?>>
Map<?, ? extends Map<?, ?>>
is also Map<Object, Object>
Map<?, ? extends Map<?, ?>>
也是Map<Object, Object>
To understand why, you need to understand how how the erasure of Map
is calculated. 要了解原因,您需要了解如何计算
Map
的删除量。 Basically, you take the type ( Map<K, V>
) and replace the formal type parameters (not the actual type parameters) with their respective least upper bound types. 基本上,您采用类型(
Map<K, V>
)并将形式类型参数(而不是实际类型参数)替换为其各自的最小上限类型。 In this case, the least upper bound type is Object
for both K
and V
, since neither have any type constraints on them ... in the Map
interface. 在这种情况下,最小的上限类型是
K
和V
Object
,因为在Map
接口中它们都没有任何类型约束。
I think I might have made up the term "least upper bound type". 我想我可能已经编造了“最小上限类型”一词。 (Sorry) But what I mean is the most specific type that is not a subtype of any of the possible types in the set that are allowed.
(对不起)但是我的意思是最具体的类型,它不是集合中允许的任何可能类型的子类型。
Another way to think of erasure is as follows. 考虑擦除的另一种方法如下。 Consider this class:
考虑此类:
public class Test <T> {
public set(T t):
}
Now imagine that we had to express that without using generics. 现在想象一下,我们必须不使用泛型来表达这一点。 What actual type would we use in place of
T
? 我们将使用什么实际类型代替
T
? In this case, it would be Object
. 在这种情况下,它将是
Object
。
And in fact, when a generic type is mapped to a runtime type, that is exactly what happens! 而事实上,当一个泛型类型映射到运行时类型,这正是发生了什么!
But, basically, you won't be able to create overloads of a method that differ only on the type parameterization of a Map
type. 但是,基本上,您将无法创建仅在
Map
类型的类型参数化方面不同的方法重载。 Unless you reify the types: 除非您更改类型:
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) {
...
}
.... which is ugly, to say the least. ....至少可以说很难看。
Solution: use different method names instead of trying to overload the same name. 解决方案:使用不同的方法名称,而不要尝试重载相同的名称。
Cannot overload a method where the formal parameter types of each overload erase to the same raw type. 无法重载每个重载的形式参数类型都擦除为相同原始类型的方法。
In your code, both method have the same signature after type erasure: 在您的代码中,两个方法在类型擦除后具有相同的签名:
public static String doSomething(Map map);
To solve your problem, you can use just two different method names instead of overloading the method. 要解决您的问题,您可以仅使用两个不同的方法名称,而不必重载该方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.