Как быстро определить, переопределяется ли метод в Java

Существует возможная оптимизация, я мог обратиться к одному из своих методов, если я могу решить, что другой метод в том же классе не переопределяется. Это - только небольшая оптимизация, таким образом отражение вне рассмотрения. Я должен просто сделать защищенный метод, который возвращается, переопределяется ли рассматриваемый метод, такой, что подкласс может заставить его возвратить true?

17
задан bgw 23 February 2010 в 00:57
поделиться

6 ответов

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

Однако если вы должны это сделать, то лучший способ - вызвать

class.getMethod("myMethod").getDeclaringClass();

Если возвращаемый класс - ваш собственный, то он не переопределен; если это что-то другое, то этот подкласс переопределил его. Да, это отражение, но это все еще довольно дешево.

Мне нравится ваш подход к защищенным методам. Это выглядело бы примерно так:

public class ExpensiveStrategy {
  public void expensiveMethod() {
    // ...
    if (employOptimization()) {
      // take a shortcut
    }
  }

  protected boolean employOptimization() {
    return false;
  }
}

public class TargetedStrategy extends ExpensiveStrategy {
  @Override
  protected boolean employOptimization() {
    return true; // Now we can shortcut ExpensiveStrategy.
  }
}
33
ответ дан 30 November 2019 в 10:58
поделиться

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

Возможно, вы захотите узнать, на что способен оптимизатор Java. Ваша ручная оптимизация может не понадобиться.

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

7
ответ дан 30 November 2019 в 10:58
поделиться

Сколько раз вы ожидаете, что функция будет вызываться за время жизни программы? Отражение для конкретного единственного метода не должно быть слишком плохим. Если это не стоит так много времени в течение срока службы программы, я рекомендую сделать ее простой и не включать небольшую оптимизацию.

Джейкоб

2
ответ дан 30 November 2019 в 10:58
поделиться

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

Вы будете видеть одни и те же классы среды выполнения снова и снова. Таким образом, вы можете сохранить результаты проверки в WeakHashMap с ключом для класса .

См. Мой код в java.awt.Component , имеющий дело с coalesceEvents в качестве примера.

0
ответ дан 30 November 2019 в 10:58
поделиться

Аннотируйте подклассы, которые переопределяют определенный метод. @OverridesMethodX.

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

1
ответ дан 30 November 2019 в 10:58
поделиться

возможно, есть более чистый способ сделать это с помощью Strategy Pattern, хотя я не знаю, как смоделированы остальные части вашего приложения и данные, но кажется, что это может подойти.

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

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

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

1
ответ дан 30 November 2019 в 10:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: