7

これは、Eclipse を使用して find をコンパイルします。

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 は抽象的ではなく、Set の抽象メソッド toArray(T[]) をオーバーライドしません

コードが Eclipse を使用してコンパイルされる理由がわかります。KeySet は CollectionView から toArray(T[]) メソッドの実装を既に継承しています。

しかし、Ant を使用してコンパイルすると失敗するのはなぜですか?

    <javac srcdir="src" destdir="bin" debug="on"> 
        <compilerarg value="-Xlint:unchecked"/>
        <compilerarg value="-Xlint:deprecation"/>
    </javac>
4

2 に答える 2

2

最初に、実装されると予想されるメソッドの正確なシグネチャは次のとおりであることに注意してください。

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

そして、両方ともjavacEclipse は、この「型の安全性」の問題について警告します。そして、署名を期待どおりのものに変更すると、javac は満足します。

@Override をメソッド toArray に配置すると、rawObject型を使用するシグネチャを使用しても、Eclipse と両方javacで によって宣言されたメソッドのオーバーライドとして正しく認識されCollectionます。したがって、この問題はありません。

javacの矛盾は、サブクラスの実装であり、実装するスーパーメソッドをjavac認識しないというバグだと思います。抽象クラスで行った場合は、すべてのサブクラスでも行う必要があります。Object[] toArray(Object[] o)<T> T[] toArray(T[] a)

javacこれに関するバグは初めてではありません。たとえば、このスレッドを参照してください。Oracle バグ データベースを検索しましたが、あなたが発見したことについて何も報告されていません。

次に回避策があります。abstrcat クラスでは、予期される署名を使用します。または、サブクラスで「手動」でオーバーライドを行います。

public Object[] toArray(Object[] o) {
    return super.toArray(o);
}
于 2013-06-12T08:40:01.473 に答える
1

Eclipse が正常にコンパイルされ、javac がコンパイルされない場合がいくつかあります。差し支えなければ、Eclipse コンパイラーを使用してビルドする方法が 3 つあります。

  1. Eclipse のコンパイル済みクラスをパッケージ化する (ハッキー、非推奨)

  2. Ant で Eclipse コンパイラー・アダプターを使用します。プロパティ build.compiler を指定すると、それ以降のすべての javac タスクが Ant ビルドに影響します。「org.eclipse.jdt.core.JDTCompilerAdapter」に設定できます。このクラス (およびそれが依存するクラス) を ant ビルド クラスパスに含める必要があることに注意してください。最も簡単な方法は、必要な jar を Ant インストールの lib フォルダーに追加することです。

  3. 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 のビルド セクションのプラグイン セクション

于 2013-06-12T09:14:08.433 に答える