6

リフレクションを使用して匿名の内部クラスのメンバーにアクセスする以外の方法はありますか?

4

7 に答える 7

9

匿名クラスの代わりにローカルクラスを使用できます。見て:

public class Test {
    public static void main(String... args) {
        class MyInner {
            private int value = 10;
        }

        MyInner inner = new MyInner();
        System.out.println(inner.value);
    }
}

ただし、タイプの参照はMyInnerメソッド本体でのみ持つことができます。java.lang.Objectそのため、メソッドの外部では、スーパークラス(この場合)またはインターフェイスで宣言されていないフィールド/メソッドを使用することはできません。

于 2008-11-26T07:08:23.353 に答える
9

匿名の内部クラスには型がありますが、名前はありません。

名前付きスーパータイプで定義されていないフィールドにアクセスできます。ただし、名前付き型変数に割り当てられると、インターフェイスは失われます。

明らかに、内部クラス自体からフィールドにアクセスできます。コードを追加する 1 つの方法は、インスタンス初期化子を使用することです。

final AtomicInteger y = new AtomicInteger();
new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
        y.set(x);
    }
    public void run() {
        ... blah ...
    }
};

匿名の内部クラス式によって返される値には匿名型があるため、クラス自体の外で使用する機会が 1 つあります。

final int y = new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
    }
    public void run() {
        ... blah ...
    }
}.x;

次のように宣言されたメソッドを介して渡すこともできます。

<T extends Runnable> T doRun(T runnable);
于 2008-11-26T11:44:28.850 に答える
1

public class AccessAnonymous {
    private Runnable runnable; // to have instance of the class

    public static void main(String[] args) throws Exception {
        AccessAnonymous a = new AccessAnonymous();
        a.a(); // init field

        Class clazz = a.runnable.getClass();
        Field field = clazz.getDeclaredField("i");
        field.setAccessible(true);

        int int1 = field.getInt(a.runnable);
        System.out.println("int1=" + int1);
    }

    public void a() {
        runnable = new Runnable() {
            private int i = 1;

            public void run() {
                i = 90;
            }

        };
        runnable.run();// change value
    }
}
于 2008-11-26T09:04:14.073 に答える
1

匿名クラスの場合、クラスが原因で混乱が生じることと、クラスを匿名にすることの利便性との間にトレードオフがあります。複雑なクラスが匿名として属することはめったになく、名前付きのプライベート 内部として属します。

ほとんどの匿名クラスでは、知識を「フィード」するだけでよく、構築時にそれを行うことができます。いくつかの無名クラス (例: 戻り値ビークル) では、1 つの戻り値も考慮します。

ご存知のように、データ メンバーには直接アクセスするのではなく、ゲッター セッターを使用してアクセスする必要があります。これは、多くのゲッターとセッターを追加した状況に陥った場合、おそらく何か間違ったことをしている可能性があり、無名クラスを使用するべきではありません。

于 2008-11-27T03:51:57.633 に答える
0

インターフェイスを実装するか、既存のクラスを拡張する場合、インターフェイスまたは基本クラスで定義されたメンバーにアクセスできます。

于 2008-11-26T06:08:52.913 に答える
0

インターフェイスが定数メンバーのみを定義できることを除いて、Fooz氏は正しいです。最良の方法は、getter/setter メソッドをインターフェイスに追加し、それらを使用して値を取得することです。しかし、匿名クラスごとに、それらのメソッドを定義する必要があります (ちょっと面倒です)。

于 2008-11-26T06:12:47.913 に答える
0

読みやすく保守しやすいコードが必要な場合は、匿名クラスを使用しないでください。匿名クラスを使用していて、読み取り可能で保守しやすいコードが必要な場合は、その内部クラスの要素にアクセスする必要があるときに匿名クラスを使用しないでください。そうする方法はありますが、それらのハックを使用しないでください。読みやすさは、他のすべての美徳に勝ります。

于 2008-11-27T01:00:41.193 に答える