3

Java 9 モジュール システムを使用しています。以下は、私の問題の簡略版です。

(モジュールで)実装するように(ClassAモジュールで)定義しました。のメソッドを実装します。このメソッドは、型のパラメーターを受け取ります(モジュール内)。以下はコードです。com.fooInterfaceBcom.barClassAprintInterfaceBClassCcom.baz

// src/a/com/foo/ClassA.java
package com.foo;

import com.bar.InterfaceB;
import com.baz.ClassC;

public class ClassA implements InterfaceB {
    @Override
    public void print(ClassC obj) {
        System.out.println(obj);
    }
} 


// src/b/com/bar/InterfaceB.java
package com.bar;

import com.baz.ClassC;

public interface InterfaceB {
    public void print(ClassC obj);
}


// src/c/com/baz/ClassC.java
package com.baz;

public class ClassC {
    @Override
    public String toString() {
        return "This is a ClassC object";
    }
}

モジュールはcom.baz何もエクスポートしません。そのため、とClassCのコンパイル中にアクセスするには、フラグを使用します。InterfaceBClassA--add-exports

InterfaceB正常にコンパイルされますが、コンパイルしようとするClassAと、次のエラーが表示されます。

src/a/com/foo/ClassA.java:6: ClassA is not abstract and does not override abstract method print(ClassC) in InterfaceB

コンパイラは何らかの形で の異なるインスタンスを使用していますClassCか? で予期しないことが起こっているような気がし--add-exportsます。

(補足として、私が使用している理由は--add-exports、私の例でcom.bazは、実際には内部 JDK パッケージであるためです。モジュール設定を変更してエクスポートすることはできません。)

4

2 に答える 2

4

モジュール システムにコードをコンパイルさせる方法は実際にありますが (すでに見つけています)、実行時にコード呼び出しInterfaceB::printがアクセスできない場合にも同様の問題が発生しますClassC。ここでも、コマンド ライン フラグを使用して修正できます。しかし、彼らはすべきではありません!

モジュールシステムは、ここで何かを伝えようとしています: 「このモジュール化は壊れています!」

以外のモジュールで のcom.baz使用を許可する必要がある場合は、ClassCそれを含むパッケージをエクスポートする必要があります。これはまさに輸出の目的です。他のコードは明らかに依存してClassCおり、モジュール システムはそのような依存関係を明示するように構築されています。したがって、コマンド ラインのオーバーライドを理解するために演習でこれを行っている場合を除き、本当の解決策はcom.baz exportを使用することcom.bazです。

(すべてのモジュールがそれを見る必要がない場合は、修飾された exportsを検討してください。リフレクションが含まれている場合は、他のアプローチの方が適している可能性があり、新しい質問をする必要があります。)

于 2016-12-02T09:16:24.797 に答える