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?
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
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.
}
}
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 WeakHashMap
keyed on the Class
.
See my code in java.awt.Component
dealing with coalesceEvents
for an example.
Annotate subclasses that overrides the particular method. @OverridesMethodX.
Perform the necessary reflective work on class load (i.e., in a static
block) so that you publish the information via a final boolean flag. Then, query the flag where and when you need it.
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.
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.
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.
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.