我偶然发现了一个我以前从未见过的有趣的错误,并且无法解释为什么
考虑下面的类
public class Sandbox<A,B> {
public void put(B b) {
}
public void put(A a) {
}
}在我看来没问题。所以我编译了它,然后得到了这个
name clash: put(B) and put(A) have the same erasure哈?两个不同的泛型如何拥有相同的签名?那是完全分开的!
我可能遗漏了一些非常基本的东西,但我以前从来没有遇到过这个问题。我已经通过调用putA和putB方法修复了这个问题,但我真的很好奇为什么会发生这个错误。
有人能解释一下吗?
发布于 2010-08-22 07:57:07
从逻辑上讲,请考虑以下代码:
SandBox<String, String> sandBox = new SandBox<String, String>();
sandBox.put("foo"); // which put is invoked?(尽管我应该承认,可以生成完全有效的代码来产生类似的情况-然后在“随机”中选择一种方法。)
从形式上讲,我认为this section of the JLS是相关的。两个版本的put都有相同的参数类型--如果我没看错的话。
发布于 2010-08-22 07:57:19
Java中的泛型仅在代码级可用,在运行时不可用。
因此,当编译器翻译你的源码时,你为A和B指定的类型就会被“擦除”。这意味着两种类型都设置为java.lang.Object。
所以你最终得到了两个相同的方法签名。
发布于 2010-08-22 07:59:20
两个不同的泛型如何拥有相同的签名?那是完全分开的!
Java泛型是基于type erasure的。这意味着你的代码基本上是这样编译的:
public class Sandbox{
public void put(Object b) {
}
public void put(Object a) {
}
}https://stackoverflow.com/questions/3539477
复制相似问题