如何快速确定是否在Java中重写了方法

如果我可以确定同一类中的另一个方法没有被覆盖,那么可以对我的一个方法应用可能的优化。 这只是一个小小的优化,所以反思是不可能的。 我是否应该创建一个受保护的方法来返回有问题的方法是否被覆盖,以便子类可以使它返回true?

我不会这样做。 它违反了封装并改变了你的类应该做的事情的合同,而没有实施者知道它。

但是,如果必须这样做,最好的方法是调用

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. } } 

好吧,我的优化是逐个案例的小收益,它只会加速很多东西,因为它每秒被调用数百次。

您可能希望了解Java优化器可以执行的操作。 您的手动编码优化可能没有必要。

如果您认为手动编码优化是必要的,那么您描述的受保护方法方法并不是一个好主意,因为它暴露了您的实现细节。

您希望在程序的生命周期内调用函数多少次? 对特定单一方法的反思不应该太糟糕。 如果在整个程序的生命周期中不值得花费那么多时间,我的建议是保持简单,并且不包括小优化。

雅各

注释覆盖特定方法的子类。 @OverridesMethodX。

对类加载执行必要的reflection工作(即,在static块中),以便通过最终布尔标志发布信息。 然后,在需要的地方和时间查询标志。

也许有一种更简洁的方法可以通过策略模式来实现这一点,但我不知道你的应用程序和数据的其余部分是如何建模的,但它似乎可能适合。

当我面对类似的问题时,它无论如何都对我有用。 您可以使用启发式方法来决定使用哪种策略,具体取决于要处理的数据。

同样,我没有足够的信息来了解您的具体用法,看看这是否有点过分。 但是,我不会为这种特定的优化更改类签名。 通常当我感觉到与现在相反的冲动时,我把它当成唱歌,当我设计这个东西时我没有预见到一个角落的情况,我应该将它重构为更清洁更全面的解决方案。

但要注意,仅在优化的基础上进行这种重构几乎不可避免地导致灾难。 如果是这种情况,我会采取上面建议的反思方法。 它不会改变inheritance契约,并且当正确完成时,只需要为每个子类执行一次,这需要它在应用程序的运行时间内。

我知道这是一个稍微陈旧的问题,但为了其他googlers:

我想出了一个使用接口的不同解决方案。

 class FastSub extends Super {} class SlowSub extends Super implements Super.LetMeHandleThis { void doSomethingSlow() { //not optimized } } class Super { static interface LetMeHandleThis { void doSomethingSlow(); } void doSomething() { if (this instanceof LetMeHandleThis) ((LetMeHandleThis) this).doSomethingSlow(); else doSomethingFast(); } private final void doSomethingFast() { //optimized } } 

或者相反:

 class FastSub extends Super implements Super.OptimizeMe {} class SlowSub extends Super { void doSomethingSlow() { //not optimized } } class Super { static interface OptimizeMe {} void doSomething() { if (this instanceof OptimizeMe) doSomethingFast(); else doSomethingSlow(); } private final void doSomethingFast() { //optimized } void doSomethingSlow(){} } 

reflection可用于确定是否覆盖方法。 代码有点棘手。 例如,您需要知道您有一个运行时类,它是覆盖该方法的类的子类。

您将一遍又一遍地看到相同的运行时类。 因此,您可以将检查结果保存在Class上的WeakHashMap

有关示例,请参阅处理coalesceEvents java.awt.Component代码。

 private static boolean isMethodImplemented(Object obj, String name) { try { Class clazz = obj.getClass(); return clazz.getMethod(name).getDeclaringClass().equals(clazz); } catch (SecurityException e) { log.error("{}", e); } catch (NoSuchMethodException e) { log.error("{}", e); } return false; }