4

Javaを書いてから約6年になりますので、さびはご容赦ください。

オブジェクトを渡す必要があるライブラリメソッドを使用していClassます。このメソッドを動的に何度も呼び出す必要があるため、毎回わずかに異なるClass引数を使用して、匿名クラスを渡したいと思いました。

ただし、これまでに見つけたすべてのドキュメント/チュートリアルでは、匿名クラスのインスタンス化についてのみ説明しています。

new className(optional argument list){classBody}

new interfaceName(){classBody}

インスタンス化せずに匿名クラスを定義できますか?または、おそらくもっと明確にClass、匿名クラスのオブジェクトを作成できますか?

4

6 に答える 6

2

残念ながら、ここでインスタンス化を回避する方法はありません。ただし、これをノーオペレーションにすることはできます。

foo((new Object() { ... }).getClass());

もちろん、コンストラクターでいくつかのアクションを実行するクラスから派生する必要がある場合、これはオプションではない可能性があります。

編集

fooあなたの質問はまた、あなたが「少しずつ異なるクラスの引数で毎回」と呼びたいと言っています。new-expressionをループに入れても、匿名の内部クラス定義は1つしか存在しないため、上記では実行されません。したがって、名前付きクラス定義と比較して、実際には何も購入することはありません。特に、一部のローカル変数の値をキャプチャしようとしている場合、渡されfooたオブジェクトを使用して作成する匿名クラスの新しいインスタンスでは、それらはキャプチャされません。Class

于 2009-07-25T19:34:28.437 に答える
1

短い答え

できません(JDKクラスのみを使用)

長い答え

試してみる:

public interface Constant {

    int value();
}

public static Class<? extends Constant> classBuilder(final int value) {
    return new Constant() {

        @Override
        public int value() {
            return value;
        }

        @Override
        public String toString() {
            return String.valueOf(value);
        }
    }.getClass();
}

2つの新しいクラス「パラメトリック」クラスを作成しましょう。

Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);

ただし、このクラスをインスタンス化することはできません。

Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto

匿名クラスごとにインスタンスが1つしかないため、実行時に失敗します。

ただし、 ASMなどのバイトコード操作ライブラリを使用して、実行時に動的クラスを構築できます。別のアプローチは動的プロキシを使用することですが、このアプローチは、インターフェイスメソッドしかプロキシできないという欠点があります(したがって、Javaインターフェイスが必要です)。

于 2009-07-25T20:02:51.127 に答える
0

匿名クラスを参照できるのは1回だけです。そこでインスタンス化しないと、名前がないためインスタンス化できません。

したがって、匿名クラスは「新しいBaseClass()」と組み合わせてのみ使用できると思います。

あなたの状況では、作業を行うメソッドにBaseClassオブジェクトを渡し、オブジェクトを渡す必要があるときにソースコードで匿名オブジェクトをインスタンス化します。

于 2009-07-25T19:23:16.027 に答える
0

匿名クラスのClassオブジェクトには、それを明示せずにアクセスすることはできません。ただし、クラスへのアクセスのみが必要な場合は、メソッド内でローカルクラスを定義し、ClassName.classリテラル構文を使用してこれらを参照できます。

于 2009-07-25T20:14:06.533 に答える
0

匿名クラスの名前を想定し、呼び出して匿名クラスClass.forName("mypackage.MyBaseClass$1")へのハンドルを取得できます。これにより、で定義された最初の匿名クラスが得られるMyBaseClassため、これはクラスを参照するためのかなり脆弱な方法です。

あなたがやろうとしていることは何でももっと良い方法でできるのではないかと思います。あなたは本当に何を達成しようとしていますか?Classおそらく、この方法を通過する必要のない方法を提案することができます。

于 2009-07-25T22:17:47.750 に答える
0

.getClass()匿名クラスのクラスオブジェクトには、作成直後に呼び出すことでアクセスできます。しかし、それは何をするのでしょうか?

重要なのはあなたが言ったことのこの部分にあると思います:

クラスオブジェクトを渡す必要があるライブラリメソッドを使用しています。

なぜクラスオブジェクトを渡してほしいのですか?このライブラリは、渡したClassオブジェクトで何をしますか?オブジェクトをインスタンス化しますか?しかし、もしそうなら、それはどのコンストラクターを使用し、どの引数を渡すかをどのように決定しますか?使用しているライブラリやその機能はわかりませんが、引数なしのコンストラクタを使用して常にオブジェクトを作成していると思います。ただし、匿名クラスにはパブリックコンストラクターがないため、これは機能しません(いずれの場合も、非静的内部クラスをインスタンス化するには、外部インスタンスへの参照を提供する必要があります。したがって、引数のないコンストラクターはありません。 )。

于 2013-04-11T08:18:39.707 に答える