为什么Java 7和Eclipse 3.8编译器不能使用新的Java 7钻石操作符编译JDK代码?

10
import java.util.*;

public class SimpleArrays
{
  @SafeVarargs
  public static <T> List<T> asList( T... a )
  {
    return new ArrayList<>( a );
  }
}
asList()方法来自于Oracle JDK实现的java.util.Arrays类。

错误是

error: cannot infer type arguments for ArrayList<>
    return new ArrayList<>( a );
1 error

这怎么可能?Oracle使用的是和我们一样的编译器。


你用javac编译过这个吗?请展示你的编译命令和javac -version的输出。 - dogbane
1
我在NetBeans中也遇到了同样的错误。但是,如果我使用javac手动尝试编译,它确实可以编译。 - toto2
经验法则是:如果你认为在Java中用三行代码发现了一个错误,那么你可能做错了什么 :) - Denis Tulskiy
2个回答

10

注意:java.util.Arrays类中使用的ArrayList不是java.util.ArrayList,而是一个嵌套类java.util.Arrays.ArrayList

特别地,这个类有一个以T[]为参数的构造函数,而java.util.ArrayList没有这个构造函数。

也要复制这个类,它会起作用。


2
我仍然在想,为什么他们选择了一个如此令人困惑的名称作为数组包装器。 - Denis Tulskiy

3

据我所知,Eclipse希望找到一个特定的类型来推断进模板化的ArrayList中。例如,如果您的方法签名是:

public static List<Integer> asList( Integer... a )

爱克立普斯(Eclipse)没有问题推断ArrayList<>( a )的类型,并推断出它的类型是Integer。我认为钻石操作符的意思就是这样运作的:推断一个特定的类型,而不是模板类型。
幸运地是,您已经将整个方法模板化,因此您可以这样形成您的语句:
      return new ArrayList<T>( a );

一切都会正常工作 :)


1
请仔细阅读:“这怎么可能?Oracle使用的是和我们一样的编译器。”该源代码原始于JDK,正如我所写的“取自Oracle JDK对java.util.Arrays的实现”。 - Hannes Licht
1
抱歉,这个答案是不正确的。原帖中的代码是完全合法的。 - M Platvoet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接