Подтвердить что ты не робот

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

Я хочу, чтобы определить, был ли метод базового класса переопределен подклассом, потому что перед его вызовом требуется дорогостоящая настройка, и большинство подклассов в нашей системе не переопределяют его. Могут ли они быть протестированы с помощью обработчиков с включенным отражением? Или есть ли другой способ проверить, переопределен ли метод класса?

например.

class BaseClass {
    void aMethod() { // don nothing }

    protected boolean aMethodHasBeenOverridden() {
        return( // determine if aMethod has been overridden by a subclass);
    } 
}
4b9b3361

Ответ 1

Вы можете сделать это с отражением, изучив класс объявления вашего метода:

class Base {
    public void foo() {}
    public void bar() {}
}
class Derived extends Base {
    @Override   
    public void bar() {}
}
...
Method mfoo = Derived.class.getMethod("foo");
boolean ovrFoo = mfoo.getDeclaringClass() != Base.class;
Method mbar = Derived.class.getMethod("bar");
boolean ovrBar = mbar.getDeclaringClass() != Base.class;
System.out.println("Have override for foo: "+ovrFoo);
System.out.println("Have override for bar: "+ovrBar);

Печать

Have override for foo: false
Have override for bar: true

Демоверсия

Ответ 2

Это можно сделать при вызове getClass().getDeclaredMethod("aMethod"), который возвращает что-то, только если класс this объявил его.

Вот реализация вашего метода:

/**
 * @return true if the instance class overrode aMethod
 */
protected boolean aMethodHasBeenOverridden() {
    try {
        return getClass() != A.class && getClass().getDeclaredMethod("aMethod") != null;
    } catch (NoSuchMethodException | SecurityException e) {
        return false;
    }
} 

Ответ 3

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

public abstract class MovingThing {
    public void move() {
        // walk a few feet
    }
}

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

public abstract class TeleportingThing extends MovingThing {
    @Override
    public void move() {
        fluxCapacitor.charge();
        stardate.calculate();
        doTeleport();
    }

    protected abstract void doTeleport();
}

Ваши классы, которые нуждаются в дорогостоящей установке, получаются из второго класса, который включает его, а те, которые не могут быть получены из первого класса. Этот шаблон является своего рода Декоратором и используется, например, в API сервлета, где большинство сервлетов переопределяют что-то вроде doGet() и оставляют синтаксический разбор service().