229

具象クラス Class1 があり、そこから匿名クラスを作成しているとしましょう。

Object a = new Class1(){
        void someNewMethod(){
        }
      };

この匿名クラスのコンストラクターをオーバーロードする方法はありますか。以下のように

Object a = new Class1(){
        void someNewMethod(){
        }
        public XXXXXXXX(int a){
          super();
          System.out.println(a);
        }
      };

コンストラクターに名前を付けるために xxxxxxxx に何かありますか?

4

10 に答える 10

297

Java言語仕様のセクション15.9.5.1から。

匿名クラスは、明示的に宣言されたコンストラクターを持つことはできません。

ごめん :(

編集:別の方法として、いくつかの最終的なローカル変数を作成したり、匿名クラスにインスタンス初期化子を含めたりすることができます。例えば:

public class Test {
    public static void main(String[] args) throws Exception {
        final int fakeConstructorArg = 10;

        Object a = new Object() {
            {
                System.out.println("arg = " + fakeConstructorArg);
            }
        };
    }
}

それはざらざらしていますが、それはあなたを助けるかもしれません。または、適切なネストされたクラスを使用します:)

于 2008-12-12T10:42:54.320 に答える
105

それは不可能ですが、次のような匿名の初期化子を追加できます。

final int anInt = ...;
Object a = new Class1()
{
  {
    System.out.println(anInt);
  }

  void someNewMethod() {
  }
};

anIntで行ったように、匿名クラスで使用されるローカル変数またはパラメーターの宣言のfinalを忘れないでください。

于 2008-12-12T10:53:05.127 に答える
79

この問題を回避する別の方法を次に示します。

public class Test{

    public static final void main(String...args){

        new Thread(){

            private String message = null;

            Thread initialise(String message){

                this.message = message;
                return this;
            }

            public void run(){
                System.out.println(message);
            }
        }.initialise(args[0]).start();
    }
}
于 2010-01-08T07:19:13.070 に答える
20

スレッドが古すぎて回答を投稿できないことはわかっています。しかし、それでも価値があると思います。

明示的なコンストラクターを使用することはできませんが、意図がスーパー クラスの (保護されている可能性がある) コンストラクターを呼び出すことである場合は、次の手順を実行するだけで済みます。

StoredProcedure sp = new StoredProcedure(datasource, spName) {
    {// init code if there are any}
};

aとobjectStoredProcedureを渡して Spring でオブジェクトを作成する例です。DataSourceString

つまり、匿名クラスを作成し、スーパー クラス コンストラクターを呼び出したい場合は、スーパー クラス コンストラクターに一致するシグネチャを持つ匿名クラスを作成します。

于 2015-09-22T11:35:58.620 に答える
3

init パラメーターを受け入れる抽象クラスにコンストラクターを含めることができます。Java 仕様では、(オプションで) 抽象クラスまたはインターフェイスの実装の子孫である匿名クラスが、それ自体でコンストラクターを持つことができないことのみを指定しています。

以下は完全に合法であり、可能です。

static abstract class Q{
    int z;
    Q(int z){ this.z=z;}
    void h(){
        Q me = new Q(1) {
        };
    }
}

抽象クラスを自分で書く可能性がある場合は、そのようなコンストラクターをそこに置き、より良い解決策がない場合は流暢な API を使用してください。このようにして、元のクラスのコンストラクターをオーバーライドして、パラメーターを持つコンストラクターで名前付き兄弟クラスを作成し、それを使用して匿名クラスをインスタンス化できます。

于 2013-01-31T12:35:08.863 に答える
2

引数を渡す必要がない場合は、イニシャライザ コードで十分ですが、contrcutor から引数を渡す必要がある場合は、ほとんどの場合を解決する方法があります。

Boolean var= new anonymousClass(){
    private String myVar; //String for example

    @Overriden public Boolean method(int i){
          //use myVar and i
    }
    public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar("Hello").method(3);
于 2012-07-28T01:24:31.080 に答える
2

Peter Norvig の The Java IAQ: よく答えられない質問

http://norvig.com/java-iaq.html#constructors - 匿名クラス コンストラクター

http://norvig.com/java-iaq.html#init - コンストラクターと初期化

合計すると、このようなものを構築できます..

public class ResultsBuilder {
    Set<Result> errors;
    Set<Result> warnings;

...

    public Results<E> build() {
        return new Results<E>() {
            private Result[] errorsView;
            private Result[] warningsView;
            {
                errorsView = ResultsBuilder.this.getErrors();
                warningsView = ResultsBuilder.this.getWarnings();
            }

            public Result[] getErrors() {
                return errorsView;
            }

            public Result[] getWarnings() {
                return warningsView;
            }
        };
    }

    public Result[] getErrors() {
        return !isEmpty(this.errors) ? errors.toArray(new Result[0]) : null;
    }

    public Result[] getWarnings() {
        return !isEmpty(this.warnings) ? warnings.toArray(new Result[0]) : null;
    }
}
于 2014-11-13T15:31:47.600 に答える
1

私の場合、ローカルクラス(カスタムコンストラクターを使用)は匿名クラスとして機能しました。

Object a = getClass1(x);

public Class1 getClass1(int x) {
  class Class2 implements Class1 {
    void someNewMethod(){
    }
    public Class2(int a){
      super();
      System.out.println(a);
    }
  }
  Class1 c = new Class2(x);
  return c;
}
于 2012-05-05T19:14:34.620 に答える
1

とにかく、それを呼び出す方法がないため、名前付きのオーバーロードされたコンストラクターを匿名クラスに持つことは意味がありません。

実際に何をしようとしているのかにもよりますが、クラス外で宣言された最終的なローカル変数にアクセスするか、Arne で示されているようにインスタンス初期化子を使用することが最善の解決策かもしれません。

于 2008-12-12T13:34:39.313 に答える