Ссылка на анонимный объект из вложенного анонимного класса - PullRequest
3 голосов
/ 02 января 2012

Можно ли сделать что-то подобное (я использую блоки инициализатора для сокращения примера)

new A() {{
  new B() {{
    method(outer.this);
  }}
}}

Где я передаю this внешнего объекта в качестве параметра для вызова метода во втором анонимномучебный класс?Я не могу использовать A.this, это дает ошибку компиляции.

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

Редактировать: пример, которыйближе к реальному варианту использования:

public class Outer {

  public SomeBean createBean() {
    return new SomeBean() {

      private final Object reference = new SomeClass() {

        @Override
        public void notify() {
          Outer.callback(/*what goes here???*/);
        }
      };

      //Methods...
    };
  }

  public static void callback(final SomeBean bean) {
    // do stuff with bean
  }
}

И ошибка компиляции, которую я получаю, заключается просто в том, что я не предоставляю правильный аргумент для обратного вызова, поскольку я не знаю, как ссылаться на подкласс SomeBean...

Ответы [ 3 ]

2 голосов
/ 02 января 2012

Если вы действительно должны , я думаю, это должно сработать.

new A() {
    {
        new B() {{
            method();
        }};
    }
    private void method() {
        method(this);
    }
}

(Историческая справка: с -target 1.3 или ранее, это должно быть NPE.)

Если вам не нужен точный тип внутреннего класса A.

new A() {
    {
        new B() {{
            method(a);
        }};
    }
    private A a() {
        return this;
    }
}
1 голос
/ 02 января 2012

@ TomHawtin - хороший ответ, мой очень похож. Я бы сделал это:

new A() {
    private final A anon = this;
    /*init*/ {
        new B() {
            /*init*/ {
                method(anon);
            }
        }
    }
}

Это, вероятно, даст вам немного лучшую производительность, чем вызов метода для получения вашего экземпляра А. Основное преимущество - IMO, его легче читать / поддерживать.

Edit: Ответ @Tomas также очень похож, но требует, чтобы вы сохранили ссылку на ваш новый объект A во внешнем внешнем классе, где он может не понадобиться.

В свете редактирования опа:

public SomeBean createBean() {
    SomeBean myBean = new SomeBean() {
        private final Object reference = new SomeClass() {
            @Override
            public void notify() {
                Outer.callback(/*what goes here???*/);
            }
        };
        //Methods...
    };
    return myBean;
}

К вашему сведению obj.notify () - последний метод в Object, вы не можете его переопределить. JavaDoc здесь

0 голосов
/ 02 января 2012

Рассмотрите возможность рефакторинга вашего кода, поскольку предлагаемый вами код не выглядит слишком логичным, и, конечно, его нелегко обрабатывать или поддерживать.Вы можете создать довольно похожую структуру (создать подклассы двух разных типов и использовать один из другого) примерно так:

//declaring a variable as final enables accessing it from the B subtype if declared at the same scope (method)
final A myA=new A() {
   //personalized content for type A
};
//then, declare the B subtype, using the final myA var as you need, at the constructor 
B myB=new B() {{
   method(myA);
}};

Это на тот случай, если вам нужно перезаписать оба класса, как вы показали.Может быть, немного переосмыслить может спасти вас от этих анонимных классов (или, по крайней мере, от некоторых из них).

...