Java Reflect/AOP override supertype private Method
Is it at all possible to "override" a private method of a super class in Java?
The class whose method I wish to override is a third party class so I cannot modify the开发者_运维技巧 source. It would be ideal if there were some way to reflectively set a method on a class.
Alternatively, if it is possible to intercept a private method of a third party class then this would be suitable.
YES. You can do it with AspectJ. It is not a true override but result will be so.
Here your super class;
public class MySuperClass {
private void content(String text) {
System.out.print("I'm super " + text);
}
public void echo() {
content("!");
}
}
Create an interface which contains similar method;
public interface Content {
void safeContent(String text);
}
Create an aspect that forces super class to implement that interface and add an around adviser to call it.
public privileged aspect SuperClassAspect {
void around(MySuperClass obj)
: execution(* content(String)) && target(obj) {
Object[] args = thisJoinPoint.getArgs();
((Content) obj).safeContent((String) args[0]);
}
// compiler requires
public void MySuperClass.safeContent(String text) {}
declare parents :MySuperClass implements Content;
}
Create your child class that extends super and implements that interface.
public class Overrider extends MySuperClass implements Content {
public void safeContent(String text) {
System.out.print("Not that super " + text);
}
}
Now if you construct a Overrider object and invoke echo method, you will have an output of Overriders safeContent's method.
Is it at all possible to "override" a private method of a super class in Java?
No
I don't think using Reflection there would be a tweak , it will break OOP
there
You do not have a legal way to do this. But I can suggest you the following solutions.
- Do you really wish to override this method? Try to think about other solution.
- Java checks access permissions during compilation only. Are you surprised? I was surprised very much to find out this fact. So you can create skeleton of the third party class (even with empty implementations.). The interesting method should be
protected
instead ofprivate
. Now write your subclass and compile it against your stub. Then package only your subclass and try to run it with the "real" class. It should work. I have not tried this trick with inheritance but I have tried it when I had to access private method or field and it worked fine for me. - Try to use dynamic proxy that wraps your class and changes its implementation. I do not know what are you doing exactly, so I am not sure you can really use this method. But I hope you can. If not go back to #1 or #2.
yes it's possible ,but you should not do it, because it contradicts one of the SOLID principles. More exactly it contradicts Liskov substitution principle.
Note: Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S, where S is a subtype of T.
So in other words , private method is property of object, so your object of inherited type must have the same property. The same with throws for methods.
Java restricts it because of it.
精彩评论