Как я могу избежать предупреждения компилятора синтетического доступа с объявлением встроенного анонимного класса и что это означает?

У меня такой код:

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. как я могу это исправить?

Спасибо


person Chris Knight    schedule 12.08.2011    source источник
comment
Дубликат stackoverflow.com/questions/921025/   -  person JB Nizet    schedule 13.08.2011
comment
@JB Низет, не совсем так. Я видел этот вопрос, который касается конкретных внутренних классов, а не анонимных. Я не могу (AFAIK) добавить конструктор в свое объявление, чтобы ошибка исчезла.   -  person Chris Knight    schedule 13.08.2011


Ответы (2)


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

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

person JB Nizet    schedule 12.08.2011
comment
Спасибо. Я не беспокоюсь о производительности, но это новая территория для меня, поэтому я хочу убедиться, что я правильно спроектировал код, поскольку он критичен для остальной части моего приложения. - person Chris Knight; 13.08.2011
comment
Последствия для безопасности? см. stackoverflow.com/a/5559064/281545. Я имею в виду, что метод больше не является частным - это частный пакет - так почему бы не объявить его как таковой (связанный с моим вопросом в stackoverflow.com/questions/17772622/ - я наконец нашел конкретный причина для не объявления частных членов Nested I доступа из Enclosing) - person Mr_and_Mrs_D; 17.10.2013
comment
Синтетические методы могут вызвать серьезные проблемы при отладке кода. Замена горячего кода не поддерживает добавление / удаление методов, но для пользователей непрозрачно, когда синтетический метод будет добавлен / удален за вашей спиной. - person Mark Jeronimus; 30.05.2014

Как насчет этого? Существует только одно объявление класса, которое должно поддерживаться вашей 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
   }
}
person David Leischnig    schedule 28.09.2012