Construtor de acesso de uma classe anónima

Digamos que tenho uma classe de betão 1 e estou a criar uma classe anónima.

Object a = new Class1(){
        void someNewMethod(){
        }
      };
Há alguma forma de sobrecarregar o construtor desta aula anónima? Como mostrado abaixo

Object a = new Class1(){
        void someNewMethod(){
        }
        public XXXXXXXX(int a){
          super();
          System.out.println(a);
        }
      };
Com algo em xxxxxxxx para nomear o construtor?

Author: Michael Myers, 2008-12-12

10 answers

Da especificação da linguagem Java , secção 15.9.5.1:

Uma classe anónima não pode ter um construtor declarado explicitamente.
Desculpa.

Editar: em alternativa, poderá criar algumas variáveis locais finais e/ou incluir um inicializador de instância na classe anónima. Por exemplo:

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

        Object a = new Object() {
            {
                System.out.println("arg = " + fakeConstructorArg);
            }
        };
    }
}
É grotesco, mas pode ajudar-te. Em alternativa, utilize uma classe aninhada adequada:)
 255
Author: Jon Skeet, 2016-12-15 22:33:39
Isso não é possível, mas você pode adicionar um inicializador anônimo como este:
final int anInt = ...;
Object a = new Class1()
{
  {
    System.out.println(anInt);
  }

  void someNewMethod() {
  }
};
Não se esqueça das declarações finais de variáveis locais ou parâmetros usados pela classe anônima, como eu fiz para o anInt.
 91
Author: Arne Burmeister, 2008-12-12 10:53:05
Há outra maneira de resolver o 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();
    }
}
 67
Author: Joel Shemtov, 2018-09-26 07:09:58
Eu sei que o fio é muito velho para postar uma resposta. Mas ainda acho que vale a pena.

Embora você não possa ter um construtor explícito, Se sua intenção é chamar o construtor da super classe, então o seguinte é tudo que você tem que fazer.

StoredProcedure sp = new StoredProcedure(datasource, spName) {
    {// init code if there are any}
};
Este é um exemplo de criação de um StoredProcedure object in Spring by passing a DataSource and a String object. Então, a questão é, se você quer criar uma classe anônima e quer chamar o super o construtor de Classes cria então a classe anónima com uma assinatura correspondente ao construtor de super classes.
 13
Author: Thirumalai Parthasarathi, 2015-09-22 11:35:58

Você pode ter um construtor na classe abstrata que aceita os parâmetros init. O Java spec apenas especifica que a classe anônima, que é a prole da classe abstrata (opcionalmente) ou implementação de uma interface, não pode ter um construtor por seu próprio direito.

O seguinte é absolutamente legal e possível:

static abstract class Q{
    int z;
    Q(int z){ this.z=z;}
    void h(){
        Q me = new Q(1) {
        };
    }
}
Se você tem a possibilidade de escrever a classe abstrata, coloque lá um construtor e use a API fluente onde não existe solucao. Você pode assim anular o construtor da sua classe original criando uma classe de irmãos com nome com um construtor com parâmetros e usá-los para instanciar a sua classe anônima.
 3
Author: Peter Verhas, 2013-01-31 12:42:14
Sim, é certo que não se pode definir construção numa classe anónima, mas não significa que a classe anónima não tenha construtor. Confundir... Na verdade, você não pode definir construção em uma classe anônima, mas o compilador gera um construtor para ele com a mesma assinatura que seu construtor pai chamado. Se o pai tiver mais do que um construtor, o anónimo terá um e apenas um construtor
 2
Author: , 2009-07-08 18:45:48

Se você não precisa passar argumentos, então o código de inicialização é suficiente, mas se você precisa passar argumentos de um contratutor há uma maneira de resolver a maioria dos casos:

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

Peter Norvig é o QIAQ Java: Respostas Pouco frequentes

Http://norvig.com/java-iaq.html#constructors - contratores anónimos de classe

Http://norvig.com/java-iaq.html#init Construção e inicialização Resumindo, podes construir algo assim..

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
Não faz sentido ter um construtor com um nome sobrecarregado numa classe anónima, como não haveria forma de lhe chamar.

Dependendo do que você está realmente tentando fazer, apenas acessar uma variável local final declarada fora da classe, ou usando um inicializador de instância como mostrado por Arne, pode ser a melhor solução.

 1
Author: Ilja Preuß, 2008-12-12 13:34:39
No meu caso, uma classe local (com construtor personalizado) funcionava como uma classe anónima:
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