JDK7编译错误:歧义引用

时间:2013-04-05 09:37:37

标签: java java-7

我正在尝试将遗留代码库从java1.6迁移到1.7,并且在编译时遇到以下错误:

  

对create的引用是不明确的,两个方法都创建(long,Object ...)   在Meta和方法中创建(对象...)元数据匹配

这里的Meta是类名。只有在使用JDK1.7进行编译时才会看到此错误。在1.6中它正在构建良好,并且所有依赖项也正常工作。

这两个多态函数如下:

 create(long id, Object... paramters) {
    ....
 }

create(Object... paramters) {
   ....
}

如何解决这个问题,以便代码适用于1.6编译和1.7编译。

编辑:添加引发错误的调用示例:

Id.create(1234);
Id.create(id); // id is a long value

2 个答案:

答案 0 :(得分:4)

这是由Java 7编译器中的修复引起的:

<强> Incompatibilities between JDK 7 and JDK 6

  

区域:工具

     

概要:大多数特定Varargs方法选择的变化

     

描述:当多个方法适用于给定的调用站点时,javac编译器中的重载决策算法已经修复了它如何选择最具体的varargs方法(参见JLS,Java SE 7 Edition,第15.12节) .2.5)。

...

  

虽然javac编译器接受的代码多于JDK 7之前的代码,但在以下情况下,此修补程序还会导致轻微的源代码不兼容:

class Test {
    void foo(int... i) {}
    void foo(Object... o) {}

    void test() {
       foo(1,2,3);
    }
}
  

此代码在JDK 6中编译(最具体的方法是foo(int ...))。此代码不在JDK 7下编译。


要使代码在两个JDK中都有效,您需要为编译器提供额外的提示以选择正确的方法,例如

Id.create(1234, new Object[0]);
Id.create(id, new Object[0]);

这将为JDK6和JDK7调用create(long id, Object... parameters),并将为varargs部分传递一个大小为0的数组,对于Java 6,也会传递原始代码。

然而,这看起来有点奇怪,我可能会选择(为了更好的可读性)重命名其中一个方法,以便方法调用不依赖于签名。

您还应该考虑Java6处于生命周期结束周期,因此可能另一种选择是修改代码,以便首先与Java7进行编译。

答案 1 :(得分:0)

很长时间被包裹在Long中成为一个物体。

那么编译器如何知道要调用哪个方法?

对于编译器,由于自动装箱,两种方法都匹配方法调用。

如果您为编译器调用create(12),则无法确定方法。因为当long被自动装入Long时,它将匹配两种方法。