How does Eclipse compile this Java code, but not Ant?

This compiler finds using 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(); } } 

but it does not compile when using Ant:

error: KeySet is not abstract and does not cancel the abstract toArray (T []) method in Set

I can understand why the code will be compiled using Eclipse: KeySet already inherits the implementation of the toArray (T []) method from CollectionView.

But why does this happen when I compile with Ant?

  <javac srcdir="src" destdir="bin" debug="on"> <compilerarg value="-Xlint:unchecked"/> <compilerarg value="-Xlint:deprecation"/> </javac> 
+7
source share
2 answers

There are several cases where compiling eclipse is fine and javac is not. If you don't mind, there are three ways that I know for creating using the eclipse compiler.

  • The eclipse package of precompiled classes (hacks, not recommended)

  • Use the eclipse compiler adapter with Ant. When you specify the build.compiler property, all javac tasks will now be affected by your Ant construct. You can install it in "org.eclipse.jdt.core.JDTCompilerAdapter". Note that you will have to include this class (and the classes on which it depends) in your path to Ant build classes. The easiest way is to add the necessary banks to the lib folder of your Ant installation

  • When creating with maven, configure this

      <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> 

in the plugins section of the build section of your pom.xml

+1
source

First, it should be noted that the exact signature of the method that is supposed to be implemented:

 <T> T[] toArray(T[] a); 

And both javac and Eclipse warn you about this type safety issue. And if you change the signature to the expected one, javac will be happy.

If you put @Override in the toArray method, even with a signature using the raw Object type, both Eclipse and javac correctly interpret this as an override of the method declared by Collection . So there is no such problem.

Inconsistency, and I think the javac error is any implementation of the subclass, javac does not recognize the super method Object[] toArray(Object[] o) for implementing <T> T[] toArray(T[] a) . If this were to be done for an abstract class, I must also do this for each subclass.

This is not the first time javac has an error about this. See this thread . I searched the Oracle database, I did not report anything about what you found.

Then there is work around: in the abstrcat class, use the expected signature; Or override "manually" in subclasses:

 public Object[] toArray(Object[] o) { return super.toArray(o); } 
+2
source

All Articles