18

外部クラスから匿名の内部クラス内で定義された新しいメソッドにアクセスするための Java 構文はありますか? さまざまな回避策があることはわかっていますが、特別な構文が存在するのだろうか?

例えば

class Outer {

    ActionListener listener = new ActionListener() {

        @Override
        void actionPerformed(ActionEvent e) { 
             // do something
        }

        // method is public so can be accessible
        public void MyGloriousMethod() {
             // viva!
        }

    };

    public void Caller() {
         listener.MyGloriousMethod(); // does not work!
    }


}

私自身の解決策

すべてのメソッドとメンバーを外部クラスに移動しました。

4

7 に答える 7

21

匿名クラス インスタンスが名前付きの型に暗黙的にキャストされると、匿名型の名前がないため、キャスト バックできません。thisクラス内、式の直後の式で匿名内部クラスの追加メンバーにアクセスでき、メソッド呼び出しによって型を推論して返すことができます。

Object obj = new Object() {
    void fn() {
        System.err.println("fn");
    }
    @Override public String toString() {
        fn();
        return "";
    } 
};
obj.toString();



new Object() {
    void fn() {
        System.err.println("fn");
    }
}.fn();


identity(new Object() {
    void fn() {
        System.err.println("fn");
    }
}).fn();
...
private static <T> T identity(T value) {
    return value;
}
于 2012-05-29T14:07:52.687 に答える
10

先日、私のクラスの生徒が私たちの教授にこれができるかどうか尋ねました. これは、それができるというクールな概念実証として私が書いたものです。それだけの価値はありませんが、実際には可能であり、その方法は次のとおりです。

public static void main(String[] args){

    //anonymous inner class with method defined inside which
    //does not override anything
    Object o = new Object()
    {
        public int test = 5;
        public void sayHello()
        {
            System.out.println("Hello World");
        }
    };

    //o.sayHello();//Does not work

    try 
    {
        Method m = o.getClass().getMethod("sayHello");
        Field f = o.getClass().getField("test");
        System.out.println(f.getInt(o));
        m.invoke(o);
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}

Java の Method クラスを利用することで、メソッドの文字列値とパラメーターを渡すことでメソッドを呼び出すことができます。フィールドでも同じことができます。

これを共有するのはクールだと思いました!

于 2014-10-10T21:33:46.577 に答える
3

呼び出し元は を知っlistenerているActionListenerため、その新しいメソッドについて何も知りません。これを行う唯一の方法は(匿名クラスを使用する目的、つまりショートカット/単純さを実際に無効にするリフレクション体操を行う以外)、単にサブクラスActionListenerを作成し、匿名クラスを使用しないことだと思います。

于 2012-05-29T14:04:07.560 に答える
1

いいえ、それは不可能です。ActionListener を実際のサブクラス名にキャストする必要がありますが、匿名であるため名前がありません。

于 2012-05-29T14:05:18.973 に答える
-2

はい、メソッドにアクセスできます。疑問がある場合は、以下の例を参照してくださいコメントしてください

package com;
interface A
{
   public void display();
}
public class Outer {
    public static void main(String []args)
    {
        A a=new A() {
        @Override
        public void display() {
            System.out.println("Hello");
        }
     };
        a.display();
    }
  }
于 2015-09-07T06:01:05.643 に答える