Accéder au constructeur d'une classe anonyme


Disons que j'ai une classe concrète Class1 et que j'en crée une classe anonyme.

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

Maintenant, est-il possible de surcharger le constructeur de cette classe anonyme. Comme indiqué ci-dessous

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

Avec quelque chose à xxxxxxxx pour nommer le constructeur?

Author: Michael Myers, 2008-12-12

10 answers

De la spécification du langage Java , section 15.9.5.1:

Une classe anonyme ne peut pas avoir constructeur explicitement déclaré.

Désolé :(

EDIT: Comme alternative, vous pouvez créer des variables locales finales et/ou inclure un initialiseur d'instance dans la classe anonyme. Par exemple:

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

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

C'est grotty, mais ça pourrait juste vous aider. Sinon, utilisez une classe imbriquée appropriée:)

 255
Author: Jon Skeet, 2016-12-15 22:33:39

Ce n'est pas possible, mais vous pouvez ajouter un initialiseur anonyme comme ceci:

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

  void someNewMethod() {
  }
};

Ne pas oublier finale sur les déclarations de variables locales ou des paramètres utilisés par la classe anonyme, comme je l'ai fait pour que vous m'avez fourni.

 91
Author: Arne Burmeister, 2008-12-12 10:53:05

Voici une autre façon de contourner le problème:

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();
    }
}
 67
Author: Joel Shemtov, 2018-09-26 07:09:58

Je sais que le fil est trop vieux pour poster une réponse. Mais encore, je pense qu'il en vaut la peine.

Bien que vous ne puissiez pas avoir de constructeur explicite, si votre intention est d'appeler le constructeur de la super classe, alors ce qui suit est tout ce que vous avez à faire.

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

Ceci est un exemple de création d'un StoredProcedure de l'objet au Printemps par le passage d'un DataSource et a String objet.

Donc, l'essentiel est, si vous voulez créer une classe anonyme et que vous voulez appeler la super classe le constructeur crée ensuite la classe anonyme avec une signature correspondant au constructeur de super classe .

 13
Author: Thirumalai Parthasarathi, 2015-09-22 11:35:58

Vous pouvez avoir un constructeur dans la classe abstract qui accepte les paramètres d'initialisation. La spécification Java spécifie uniquement que la classe anonyme, qui est la progéniture de la classe abstraite (éventuellement) ou de l'implémentation d'une interface, ne peut pas avoir de constructeur de son propre chef.

Ce qui suit est absolument légal et possible:

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

Si vous avez la possibilité d'écrire vous-même la classe abstraite, mettez-y un tel constructeur et utilisez l'API fluent là où il n'y a pas mieux solution. Vous pouvez ainsi remplacer le constructeur de votre classe d'origine en créant une classe frère nommée avec un constructeur avec des paramètres et l'utiliser pour instancier votre classe anonyme.

 3
Author: Peter Verhas, 2013-01-31 12:42:14

Oui , il est juste que vous ne pouvez pas définir construct dans une classe Anonyme mais cela ne signifie pas que la classe anonyme n'a pas de constructeur. Confondre... En fait, vous ne pouvez pas définir construct dans une classe anonyme, mais le compilateur génère un constructeur avec la même signature que son constructeur parent appelé. Si le parent a plus d'un constructeur, l'anonyme aura un et un seul constructeur

 2
Author: , 2009-07-08 18:45:48

Si vous n'avez pas besoin de passer des arguments, alors le code d'initialisation est suffisant, mais si vous devez passer des arguments d'un contrcutor, il existe un moyen de résoudre la plupart des cas:

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);
 2
Author: Whimusical, 2012-07-28 01:24:31

The Java IAQ de Peter Norvig: Questions rarement Répondues

Http://norvig.com/java-iaq.html#constructors - Contructeurs de classe anonyme

Http://norvig.com/java-iaq.html#init - Construtors et l'initialisation

En sommant, vous pouvez construire quelque chose comme ceci..

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;
    }
}
 2
Author: Diogo Quintela, 2014-11-13 15:31:47

Cela n'a aucun sens d'avoir un constructeur surchargé nommé dans une classe anonyme, car il n'y aurait aucun moyen de l'appeler, de toute façon.

Selon ce que vous essayez réellement de faire, le simple accès à une variable locale finale déclarée en dehors de la classe, ou l'utilisation d'un initialiseur d'instance comme indiqué par Arne, pourrait être la meilleure solution.

 1
Author: Ilja Preuß, 2008-12-12 13:34:39

Dans mon cas, une classe locale (avec un constructeur personnalisé) fonctionnait comme une classe anonyme:

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;
}
 1
Author: arnaldocan, 2012-12-07 00:20:10