Как можно избежать синтетического предупреждения компилятора доступа с помощью встроенного анонимного объявления класса и что это значит? - PullRequest
3 голосов
/ 13 августа 2011

У меня есть следующий код:

public class SomeClass {
   //InterfaceUpdateListener is an interface
   private InterfaceUpdateListener listener = new InterfaceUpdateListener(){
        public void onUpdate() {
           SomeClass.this.someMethod();  //complier complains on this line of code
        }
   };

   private void someMethod() {
     //do something in here on an update event occuring
   }

   //other code to register the listener with another class...
}

Мой компилятор в Eclipse жалуется, что

Access to enclosing method 'someMethod' from type SomeClass is emulated by a synthetic accessor method.

Может кто-нибудь объяснить точно

  1. что это значит,
  2. что могут означать возможные последствия, если я оставлю все как есть (поскольку это только предупреждение), и
  3. как я могу это исправить?

Спасибо

Ответы [ 2 ]

4 голосов
/ 13 августа 2011

Я бы просто деактивировал правило (то есть, чтобы компилятор не генерировал предупреждение для этого). Если конструкция допустима, и если компилятор добавляет дополнительный метод для ее поддержки, то это так и должно быть.

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

2 голосов
/ 28 сентября 2012

Как насчет этого? Существует только одно объявление класса, которое должно поддерживаться вашей JVM (PermGen), реализующий класс все еще недоступен за пределами SomeClass (я думаю, что это единственное законное намерение написать вложенный класс в любом случае), и последнее, но не менее важное, что вы могли бы также предоставить второй конструктор с InterfaceUpdateListener в качестве аргумента (если это необходимо для большей гибкости и тестируемости). И нет необходимости менять предупреждения.

ожидать

public interface InterfaceUpdateListener {
    public void onUpdate();
}

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

public class SomeClass {
   //InterfaceUpdateListener is an interface
   private final InterfaceUpdateListener listener;
   private static class SomeClassInterfaceUpdateListener implements InterfaceUpdateListener {
       private final SomeClass internal;
       public SomeClassInterfaceUpdateListener(final SomeClass aSomeClass) {
           internal = aSomeClass;
       }
       @Override
       public void onUpdate() {
           internal.someMethod();  //complier complains on this line of code
       }
   }
   public SomeClass() {
       listener =  new SomeClassInterfaceUpdateListener(this);
   }
   private void someMethod() {
     //do something in here on an update event occuring
   }
}
...