如何快速确定一个方法是否在 Java 中被覆盖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2315445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to quickly determine if a method is overridden in Java
提问by bgw
There is a possible optimization I could apply to one of my methods, if I can determine that another method in the same class is not overridden. It is only a slight optimization, so reflection is out of the question. Should I just make a protected method that returns whether or not the method in question is overridden, such that a subclass can make it return true?
如果我可以确定同一类中的另一个方法没有被覆盖,我可以对我的一个方法应用一种可能的优化。这只是一个轻微的优化,所以反射是不可能的。我是否应该创建一个受保护的方法来返回所讨论的方法是否被覆盖,以便子类可以使其返回 true?
回答by John Feminella
I wouldn't do this. It violates encapsulation and changes the contract of what your class is supposed to do without implementers knowing about it.
我不会这样做。它违反了封装并改变了你的类应该做的事情的契约,而实现者不知道它。
If you must do it, though, the best way is to invoke
但是,如果您必须这样做,最好的方法是调用
class.getMethod("myMethod").getDeclaringClass();
If the class that's returned is your own, then it's not overridden; if it's something else, that subclass has overridden it. Yes, this is reflection, but it's still pretty cheap.
如果返回的类是你自己的,那么它不会被覆盖;如果是别的东西,那个子类已经覆盖了它。是的,这是反射,但它仍然很便宜。
I do like your protected-method approach, though. That would look something like this:
不过,我确实喜欢你的保护方法方法。那看起来像这样:
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.
}
}
回答by jdigital
Well, my optimization is a small yield on a case-by-case basis, and it only speeds things a lot because it is called hundreds of times per second.
好吧,我的优化是逐案的小收益,它只会加快速度,因为它每秒被调用数百次。
You might want to see just what the Java optimizer can do. Your hand-coded optimization might not be necessary.
您可能想看看 Java 优化器可以做什么。您可能不需要手动编码优化。
If you decide that hand-coded optimization is necessary, the protected method approach you described is not a good idea because it exposes the details of your implementation.
如果您决定手动编码优化是必要的,则您描述的受保护方法方法不是一个好主意,因为它暴露了您的实现细节。
回答by TheJacobTaylor
How many times do you expect the function to be called during the lifetime of the program? Reflection for a specific single method should not be too bad. If it is not worth that much time over the lifetime of the program my recommendation is to keep it simple, and don't include the small optimization.
您希望在程序的生命周期内调用该函数多少次?对特定单一方法的反射应该不会太糟糕。如果在程序的整个生命周期内不值得花那么多时间,我的建议是保持简单,不要包括小的优化。
Jacob
雅各布
回答by Newtopian
maybe there is a cleaner way to do this via the Strategy Pattern, though I do not know how the rest of your application and data are modeled but it seem like it might fit.
也许有一种更简洁的方法可以通过Strategy Pattern做到这一点,尽管我不知道您的应用程序和数据的其余部分是如何建模的,但它似乎可能适合。
It did to me anyhow when I was faced with a similar problem. You could have a heuristic that decides which strategy to use depending on the data that is to be processed.
无论如何,当我遇到类似的问题时,它确实对我有用。您可以使用启发式方法,根据要处理的数据决定使用哪种策略。
Again, I do not have enough information on your specific usage to see if this is overkill or not. However I would refrain from changing the class signature for such specific optimization. Usually when I feel the urge to go against the current I take it as a sing that I had not forseen a corner case when I designed the thing and that I should refactor it to a cleaner more comprehensive solution.
同样,我没有关于您的具体用法的足够信息来查看这是否矫枉过正。但是,我会避免更改此类特定优化的类签名。通常,当我感到逆流而上的冲动时,我认为我在设计这个东西时没有预见到极端情况,我应该将它重构为一个更清洁、更全面的解决方案。
however beware, such refactoring when done solely on optimization grounds almost inevitably lead to disaster. If this is the case I would take the reflecive approach suggested above. It does not alter the inheritance contract, and when done properly needs be done once only per subclass that requires it for the runtime life of the application.
但是请注意,仅基于优化原因进行的此类重构几乎不可避免地会导致灾难。如果是这种情况,我会采用上面建议的反射方法。它不会改变继承契约,并且当正确完成时,只需要为每个在应用程序的运行时生命周期中需要它的子类完成一次。
回答by SimonPe
I know this is a slightly old question, but for the sake of other googlers:
我知道这是一个有点老的问题,但为了其他谷歌员工:
I came up with a different solution using interfaces.
我想出了一个使用接口的不同解决方案。
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
}
}
or the other way around:
或者反过来:
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(){}
}
回答by kayz1
private static boolean isMethodImplemented(Object obj, String name)
{
try
{
Class<? extends Object> clazz = obj.getClass();
return clazz.getMethod(name).getDeclaringClass().equals(clazz);
}
catch (SecurityException e)
{
log.error("{}", e);
}
catch (NoSuchMethodException e)
{
log.error("{}", e);
}
return false;
}
回答by Noel Ang
Annotate subclasses that overrides the particular method. @OverridesMethodX.
注释覆盖特定方法的子类。@OverridesMethodX。
Perform the necessary reflective work on class load (i.e., in a staticblock) so that you publish the information via a final boolean flag. Then, query the flag where and when you need it.
对类加载(即在static块中)执行必要的反射工作,以便您通过最终的布尔标志发布信息。然后,在需要的地方和时间查询标志。
回答by Tom Hawtin - tackline
Reflection can be used to determine if a method is overridden. The code is a little bit tricky. For instance, you need to be aware that you have a runtime class that is a subclass of the class that overrides the method.
反射可用于确定方法是否被覆盖。代码有点棘手。例如,您需要知道您有一个运行时类,它是覆盖该方法的类的子类。
You are going to see the same runtime classes over and over again. So you can save the results of the check in a WeakHashMapkeyed on the Class.
您将一遍又一遍地看到相同的运行时类。因此,您可以将检查结果保存WeakHashMap在Class.
See my code in java.awt.Componentdealing with coalesceEventsfor an example.
以我的代码java.awt.Component处理coalesceEvents为例。

