使用Eclipse编译查找:
abstract class CollectionView implements Collection<Object> {
...
public Object[] toArray(Object[] o) {
if (fast) {
return get(map).toArray(o);
} else {
synchronized (map) {
return get(map).toArray(o);
}
}
}
...
}
class KeySet extends CollectionView implements Set<Object> {
protected Collection<Object> get(Map<Object, Object> map) {
return map.keySet();
}
protected Object iteratorNext(Map.Entry entry) {
return entry.getKey();
}
}
但是在使用Ant时编译失败:
错误:KeySet不是抽象的,也没有覆盖抽象方法toArray(T[]) in Set
我可以看到为什么代码会使用Eclipse编译:KeySet已经从CollectionView继承了toArray(T[])方法的实现。
但是为什么当我使用Ant编译时它会失败?
<javac srcdir="src" destdir="bin" debug="on">
<compilerarg value="-Xlint:unchecked"/>
<compilerarg value="-Xlint:deprecation"/>
</javac>
首先,我们应该注意要实现的方法的确切签名是:
<T> T[] toArray(T[] a);
javac
和Eclipse都警告您这个"类型安全"问题。如果您将签名更改为期望的签名,javac将很高兴。
如果你把@Override方法toArray,即使使用原始Object
类型的签名,Eclipse和javac
都正确地将其视为Collection
声明的方法的重写。所以这个问题不存在。
不一致,我认为javac
的bug,是任何子类实现,javac
不识别超方法Object[] toArray(Object[] o)
来实现<T> T[] toArray(T[] a)
。如果它为抽象类做了,那么它也应该为每个子类做。
这不是javac
第一次有这样的错误。请看下面这个线程的例子。我已经搜索了Oracle错误数据库,我没有发现任何关于你所发现的报告。
然后有一个解决办法:在抽象类中,使用预期的签名;或者在子类中"手动"重写:
public Object[] toArray(Object[] o) {
return super.toArray(o);
}
在一些情况下,eclipse可以很好地编译,而javac不能。如果您不介意的话,我知道有三种方法可以使用eclipse编译器进行构建。
-
打包eclipse预编译类(不推荐)
-
与Ant一起使用eclipse编译器适配器。当您指定属性build.compiler时,所有javac任务都将在Ant构建中受到影响。您可以将其设置为"org.eclipse.jdt.core.JDTCompilerAdapter"。注意,您必须在ant构建类路径中包含这个类(以及它所依赖的类)。最直接的方法是将必要的jar文件添加到Ant安装的lib文件夹
-
当使用maven构建时,配置这个
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <compilerId>eclipse</compilerId> <compilerVersion>1.6</compilerVersion> <source>1.6</source> <target>1.6</target> <optimize>true</optimize> </configuration> <dependencies> <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-compiler-eclipse</artifactId> <version>2.2</version> </dependency> </dependencies> </plugin>
在pom.xml的构建部分的插件部分