Java中的类型擦除

Java中的类型擦除,java,collections,type-conversion,type-erasure,Java,Collections,Type Conversion,Type Erasure,我必须处理嵌套集合(例如,列表映射或映射映射),这就是我要处理它的方式: public static String doSomething(Map<?, ? extends Collection<?>> map) { ... } public static String doSomething(Map<?, ? extends Map<?, ?>> map) { ... } publicstaticstrin

我必须处理嵌套集合(例如,列表映射或映射映射),这就是我要处理它的方式:

  public static String doSomething(Map<?, ? extends Collection<?>> map) {
     ...
  }

  public static String doSomething(Map<?, ? extends Map<?, ?>> map) {
     ...
  }
publicstaticstringdosomething(Map>Map){
...
}
公共静态字符串doSomething(映射>映射){
...
}

但编译器告诉我,上述两种方法具有相同的类型擦除。我想知道为什么,因为我已经指定了不同的类型边界。

无法重载一个方法,其中每个重载的形式参数类型将擦除为相同的原始类型

在您的代码中,两个方法在类型擦除后具有相同的签名:

public static String doSomething(Map map);
要解决您的问题,您可以只使用两个不同的方法名称,而不是重载该方法。

Map>
的擦除是
Map

Map>
的擦除也是
Map

要了解原因,您需要了解如何计算
Map
的擦除。基本上,您采用类型(
Map
)并用它们各自的最小上限类型替换形式类型参数(而不是实际的类型参数)。在这种情况下,
K
V
的最小上限类型都是
Object
,因为它们都没有任何类型约束。。。在
Map
界面中

我想我可能编造了“最小上界类型”这个词。(抱歉)但我的意思是最具体的类型,它不是集合中允许的任何可能类型的子类型


另一种思考擦除的方式如下。考虑这个类:

public class Test <T> {
    public set(T t):
}
。。。。至少可以说,这是丑陋的


解决方案:使用不同的方法名,而不是试图重载相同的名称。

您是否阅读了类型擦除?应用它后,这两种方法看起来都像
公共静态字符串doSomething(Map-Map)
。我已经读过了,但有人能解释为什么不使用Map和Map吗?从您的评论中,我得出一个结论,即行。。。extends Collection>只是无用的,取决于您想做什么
?扩展集合
可能有用,也可能无用。这些泛型类型只是对编译器的提示,也就是说,如果您试图传入一个
映射
,编译器将识别出
字符串
扩展集合
边界不匹配,并产生一个错误。是的,这是有效的,因为编译器将能够推断出
t
的最小类型,即第一种情况下的
集合
,以及
列表
在第二个。但是,这只在一个级别上起作用,因此
Map>
仍然只会导致
Map
(您也可以认为它会发生两次,即第一步将导致
Map
,而第二步将导致
Map
).因此,如果没有instanceof之类的东西,我无论如何也无法确定集合是否嵌套在编译类型中?@KonstantinK你怎么称呼它?编译器必须在编译时进行区分,这样您就可以调用不同的方法(例如,使用不同的名称或在不同的类中)。在编译类型中,我有类型Map或mapThank,这比引用在Java中,类型擦除是当泛型类型被实例化时,编译器在类或方法中删除与类型参数和类型参数相关的所有信息的过程“。我读了这篇文章,但我被误导了,认为边界将在某种程度上影响使用哪种方法的推理。我在泛型教程中看到过这种情况。但当我们有界类型时,例如。T是可序列化的吗?与这种情况的类比让我感到困惑(我认为如果我使用有界通配符,就会发生这种类型的擦除)。@KonstantinK-事实上,你真正困惑的原因是你考虑的是实际的类型参数,而不是形式的类型参数。如果简单,形式参数是我在方法签名中传递的,实际的-调用时在代码中传递的,对吗?我的主要缺点是我没有完全理解擦除是如何工作的,就像托马斯在评论中所说的那样。
  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) {
     ...
  }