Анонимный класс внутри анонимного класса - столкновение имен функций - PullRequest
0 голосов
/ 23 мая 2018

Я знаю, что это действительно редкая вещь, но сегодня со мной это произошло по-настоящему, после того как я сделал рефакторинг функции с именем "progress" в "setProgress".У меня есть этот код, создающий объект анонимного подтипа SwingWorker, и в его методе "doInBackground" у меня есть еще один вызов функции для моего собственного типа, который также анонимно типизирован.Оказывается, что оба типа имеют одинаковую функцию setProgress.Примечание. SwingWorkerEx - это просто пользовательский подтип SwingWorker.

new SwingWorkerEx<Void, Void>() {
          @Override
          protected Void doInBackground() throws Exception {
            final SwingWorkerEx self = this;
            lazyNode.loadForce(_dao, new ProgressListener() {
              @Override
              public void setProgress(@Nullable ProgressOperation operation, int percent) {
                setProgress(percent);
              }
            });
            return null;
          }

Полученная ошибка:

setProgress (ProgressOperation, int) in ... не может быть применена к (int)

Java, очевидно, думает, что я пытаюсь сослаться на внутренние методы setProgress класса, и думает, что я неправильно понял параметры.К счастью, сигнатуры функций не совпадают, или мне придется иметь дело с бесконечной рекурсией позже!Я пытаюсь устранить неоднозначность, но не могу.Я даже попробовал это решение: Как сослаться на включающий экземпляр анонимного класса в Java? , выполнив следующее:

 protected Void doInBackground() throws Exception {
            final SwingWorkerEx self = this;

И

@Override
              public void setProgress(@Nullable ProgressOperation operation, int percent) {
                self.setProgress(percent);
              }

Но тонкостьмодификаторы доступа поймали меня.В частности, Java жаловалась:

'setProgress (int)' имеет защищенный доступ в 'javax.swing.SwingWorker'

Некоторые заметки

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

Еще одна вещь, о которой я подумал, - это извлечь функцию SwingWorker как тип Function, а затем передать эту функцию во вложенный анонимный класс, но, увы, это voidтип!И сделать его Void (заглавной V) - это просто обходной путь, а не решение.Определение именного класса IMO в любом случае является лучшим решением.

Еще одна вещь, которая не сработала, - это переопределение функции setProgress в анонимном подтипе SwingWorkerEx:

@Override
public void setProgress(int percent){super.setProgress(percent);}

Это потому, чтофункция является окончательной в SwingWorker.

1 Ответ

0 голосов
/ 24 мая 2018

Для тех, кто сталкивается с этой проблемой, вот обходной путь.Я не приму это, хотя, поскольку это не решение.Возможно, решения не существует.

В анонимном подклассе SwingWorkerEx определите эту функцию:

public void setProgressSuper(int percent){super.setProgress(percent);}

Затем вызовите ее в анонимной реализации ProgressListener в функции doInBackground:

@Override
              public void setProgress(@Nullable ProgressOperation operation, int percent) {
                setProgressSuper(percent);
              }
            });

Собираем все вместе:

  new SwingWorkerEx<Void, Void>() {

      //Need this as a workaround to accessing the protected function in the anonymous ProgressListener class below
      public void setProgressSuper(int percent){super.setProgress(percent);}

      @Override
      protected Void doInBackground() throws Exception {      
        lazyNode.loadForce(_dao, new ProgressListener() {

          @Override
          public void setProgress(@Nullable ProgressOperation operation, int percent) {
            setProgressSuper(percent);
          }
        });
        return null;
      }
...
...