Domanda

Diciamo che ho un cemento di classe Class1 e sto creando una classe anonima fuori di esso.

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

Ora c'è un modo ho potuto sovraccaricare il costruttore di questa classe anonima.Come mostrato di seguito

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

Con qualcosa a xxxxxxxx a nome del costruttore?

È stato utile?

Soluzione

linguaggio Java specifiche , sezione 15.9.5.1:

  

Una classe anonima non può avere un   esplicitamente dichiarato costruttore.

Siamo spiacenti: (

EDIT: In alternativa, è possibile creare alcune variabili locali finali, e / o includere un inizializzatore esempio nella classe anonima. Ad esempio:

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

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

E 'brutta, ma potrebbe solo aiutare. In alternativa, utilizzare una vera e propria classe annidata:)

Altri suggerimenti

Questo non è possibile, ma è possibile aggiungere un inizializzatore anonima in questo modo:

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

  void someNewMethod() {
  }
};

Non dimenticare finale sulle dichiarazioni di variabili locali o parametri utilizzati dalla classe anonima, come ho fatto per anInt.

Ecco un altro modo per aggirare il problema:

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();
    }
}

So che il filo è troppo vecchio per inviare una risposta. Ma ancora penso che sia valsa la pena.

Anche se non si può avere un costruttore esplicito, se la vostra intenzione è quella di chiamare il costruttore della classe super, allora la seguente è tutto quello che dovete fare.

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

Questo è un esempio di creazione di un StoredProcedure oggetto in primavera passando un DataSource e un String oggetto

Così la linea di fondo è, se si vuole creare una classe anonima e si desidera chiamare il costruttore super-classe quindi creare la classe anonima con un firma corrispondente al costruttore di super-classe .

Si può avere un costruttore nella classe astratta che accetta i parametri di inizializzazione. Il Java spec specifica solo che la classe anonima, che è il figlio del (opzionalmente) classe o implementazione di un'interfaccia astratta, non può avere un costruttore da suo pieno diritto.

Quello che segue è assolutamente legale e possibile:

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

Se avete la possibilità di scrivere la classe astratta da soli, mettere una tale costruttore di lì e utilizzare API fluente dove non c'è soluzione migliore. È possibile in questo modo ignorare la costruzione della classe di originale creando una classe fratello di nome con un costruttore con i parametri e l'uso che per istanziare la classe anonima.

Sì, è giusto che non è possibile definire costrutto in una classe anonima, ma ciò non significa che la classe anonima non hanno costruttore. Confuso... In realtà non è possibile definire costrutto in una classe anonima, ma compilatore genera un costruttore con la stessa firma il costruttore genitore chiamato. Se il genitore ha più di un costruttore, l'anonimo avrà uno e un solo costruttore

Se non avete bisogno di passare gli argomenti, quindi initializer codice è sufficiente, ma se avete bisogno di passare gli argomenti da un contrcutor c'è un modo per risolvere la maggior parte dei casi:

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);

Peter Norvig Il Java IAQ:Di Rado Risposto Alle Domande

http://norvig.com/java-iaq.html#constructors - Classe anonima contructors

http://norvig.com/java-iaq.html#init - Construtors e inizializzazione

Riassumendo, si può costruire qualcosa di simile..

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;
    }
}

Non ha alcun senso per avere un costruttore di overload di nome in una classe anonima, in quanto non vi sarebbe alcun modo per chiamarlo, in ogni caso.

A seconda di cosa si sta effettivamente cercando di fare, solo l'accesso a una variabile locale finale dichiarata al di fuori della classe, o utilizzando un inizializzatore esempio come mostrato da Arne, potrebbe essere la soluzione migliore.

Nel mio caso, una classe locale (con il costruttore personalizzato) ha lavorato come una classe anonima:

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top