Доступ к конструктору анонимного класса

Позволяет сказать, что у меня есть конкретный класс Class1, и я создаю из него анонимный класс.

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

Теперь я могу перегрузить конструктор этого анонимного класса. Как показано ниже

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

С чем-то в xxxxxxxx, чтобы назвать конструктор?

Ответ 1

Из Спецификация языка Java, раздел 15.9.5.1:

Анонимный класс не может иметь явно объявленный конструктор.

Извините: (

EDIT: в качестве альтернативы вы можете создать некоторые конечные локальные переменные и/или включить инициализатор экземпляра в анонимный класс. Например:

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

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

Это громоздко, но это может просто помочь вам. Кроме того, используйте правильный вложенный класс:)

Ответ 2

Это невозможно, но вы можете добавить анонимный инициализатор следующим образом:

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

  void someNewMethod() {
  }
};

Не забывайте final на объявлениях локальных переменных или параметров, используемых анонимным классом, как я сделал это для anInt.

Ответ 3

Здесь другой путь проблемы:

public class Test{

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

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

Ответ 4

Я знаю, что поток слишком стар, чтобы опубликовать ответ. Но все же я думаю, что это того стоит.

Хотя у вас не может быть явного конструктора, если вы намерены вызвать конструктор суперкласса, то вам нужно все это сделать.

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

Это пример создания StoredProcedure объекта Spring, передав DataSource и String объект.

Итак, нижняя строка: если вы хотите создать анонимный класс и хотите вызвать конструктор суперкласса, тогда создайте анонимный класс с помощью подписи, соответствующей конструктору суперкласса.

Ответ 5

У вас может быть конструктор абстрактного класса, который принимает параметры init. Спецификация Java указывает только, что анонимный класс, являющийся потомком (необязательно) абстрактного класса или реализации интерфейса, не может иметь конструктор по своему усмотрению.

Следующее абсолютно юридическое и возможное:

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

Если у вас есть возможность написать абстрактный класс самостоятельно, поставьте туда такой конструктор и используйте свободный API, в котором нет лучшего решения. Вы можете таким образом переопределить конструктор исходного класса, создав класс с именем sibling с конструктором с параметрами и использовать его для создания вашего анонимного класса.

Ответ 6

Да. Правильно, что вы не можете определить конструкцию в анонимном классе, но это не значит, что анонимный класс не имеет конструктора. Путать... На самом деле вы не можете определить конструкцию в анонимном классе, но компилятор генерирует для нее конструктор с той же сигнатурой, что и его родительский конструктор. Если у родителя имеется более одного конструктора, анонимный будет иметь один и только один конструктор

Ответ 7

Если вам не нужно передавать аргументы, то код инициализатора достаточно, но если вам нужно передать аргументы от исполнителя, есть способ решить большинство случаев:

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

Ответ 8

Не имеет никакого смысла иметь именованный перегруженный конструктор в анонимном классе, так как в любом случае его нельзя было бы назвать.

В зависимости от того, что вы на самом деле пытаетесь сделать, лучшим решением может стать доступ к последней локальной переменной, объявленной вне класса, или использование инициализатора экземпляра, как показано Арне.

Ответ 9

В моем случае локальный класс (с настраиваемым конструктором) работал как анонимный класс:

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

Ответ 10

Питер Норвиг. 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;
    }
}