5

日食 3.4。Java 编译器级别 1.6 JRE IBM 1.6

我们有一个库类,我们无法更改它的形式。

import java.util.Hashtable;
public class A extends Hashtable {
  ...
}

我们已经构建了一个实用程序类来提供对 A 的轻松访问。

public class B {
  private A a;
  public B() {
    this.a = new A();
  }
  public B(final A props) {
    this.a = props;
  }
  public B(final Map<String, String> props) {
    this();
    for (String key : props.keySet()) {
      add(key, props.get(key));
    }
  }
  @SuppressWarnings("unchecked")
  public B add(final String name, final Object value) {
    a.put(name, value);
    return this;
  }
}

当我们尝试从另一个类调用其中一个构造函数时,就会出现问题。

public class C {

  public void stuff() {
    A a = new A();
    B b = new B(a);//Error in javac
  }
}

Eclipse 编译它没有错误,当它通过 ant javac 和 jenkins 编译时,编译器会给出如下错误。

reference to B is ambiguous, both method B(com.foo.A) in com.bar.B and method B(java.util.Map<java.lang.String,java.lang.String>) in com.bar.B match
    [javac]         B b = new B(a);

这个错误应该发生在 javac 中吗?在我看来,eclipse 在选择更具体的方法方面是正确的。

4

3 回答 3

0

问题是一个构造函数接受一个原始的 Hashtable,而另一个接受一个参数化的 Map。两个构造函数都适用,但是在这种情况下,消歧逻辑不起作用,因为根据Java 语言规范- 只有当它的参数是另一个参数的(严格)子类型时,一个构造函数才会比另一个更具体。在此阶段不允许未经检查的子类型化,因此存在歧义。

于 2012-09-27T13:24:33.203 回答
0

由于HashTable实现了Map,所以存在歧义。H这个答案包含一些很好的见解:

在 Java 中调用模糊重载的构造函数

于 2012-09-26T07:59:57.383 回答
-1

由于A类扩展了Hashtable,而Hashtable本身实现了Map接口,所以可以说A类得到了Map的属性,也变成了Map。

当您拥有public B(final A props)and时public B(final Map<String, String> props) ,就像您在两个构造函数中都有一个 map 参数一样。

这就是为什么它给你带来歧义。

于 2012-09-26T09:18:48.423 回答