0

次の問題に遭遇しました。

パッケージに 2 つの異なるパッケージがあり、aパッケージ内のインターフェイスの実装されたメソッドを呼び出したいのですbが、実装するクラスにはパッケージの可視性があります。

したがって、単純化されたコードは次のようになります。

package b;

public final class Factory {
    public static B createB() {
        return new ImplB();
    }

    public interface B {
        void method();
    }

    static class ImplB implements B {
        public void method() {
            System.out.println("Called");
        }
    }
}

そして呼び出し元:

package a;

import java.lang.reflect.Method;
import b.Factory;
import b.Factory.B;

public final class Invoker {
    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[] {};
    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[] {};

    public static void main(String... args) throws Exception {
        final B b = Factory.createB();
        b.method();

        final Method method = b.getClass().getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
        method.invoke(b, EMPTY_OBJECT_ARRAY);
    }
}

プログラムを開始すると、パッケージの可視性が検出されたメソッドの呼び出しを禁止しているため、期待どおりに出力さCalledれ、例外がスローされます。

だから私の質問は、この問題を解決する方法はありますか? 私はJavaドキュメントに何か欠けているのでしょうか、それとも単純に実装されたメソッドをリフレクションなしで呼び出すことは可能ですが、これは単に不可能です.

4

3 に答える 3

3

クラスにはパッケージの可視性があるため、そのメソッドの可視性は、実際にはパブリックではなくパッケージレベルです。したがって、method.setAccessible(true)メソッド呼び出しの前に呼び出す必要があります。

 final Method method = b.getClass().getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
 method.setAccessible(true);
 method.invoke(b, EMPTY_OBJECT_ARRAY);
于 2012-10-04T15:36:22.607 に答える
1

分かった。getDeclaredMethodクラスではなく、実装されたインターフェイスでを呼び出す必要があります。

例:

final Method method = B.class.getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
method.invoke(b, EMPTY_OBJECT_ARRAY);
于 2012-10-04T15:35:22.347 に答える
0

setAccessibleのドキュメントを参照してください。ただし、SecurityPolicy により、アクセス可能にできない場合があります。

しかし、反省がまったく必要かどうかは明らかではありません。ポリモーフィズムの利点の 1 つは、クライアントがB.method()インターフェイスを実装する具象クラスにアクセスせずに (または気にせずに) 呼び出すことができることです。

于 2012-10-04T15:40:24.463 に答える