我想替换一个我知道源代码的类的函数。问题是我不能重写函数,因为它是私有的,而且我也不能扩展类并重写整个功能,因为坏的调用在每个可能的构造函数中。
现在我完全迷失了,我不知道如何实现所需的功能(Android VideoView控件的主题控制又名MediaController)。有没有办法用反射或类似的东西来代替函数?或者甚至有可能不调用超类的构造函数,而调用超超类?
这是一个非常基本的类,它显示了我的问题:
public class Base {
public Base(int state) {
// must be called
}
}
public class Example extends Base {
public Example(int state, boolean bla) {
super(state);
badCall();
}
public Example(int state) {
this(state, false);
}
private badCall() {
// doing bad things
}
}
还要注意,我需要有一个Example
的实例,所以我不能简单地复制这个类。
下面是一个使用模拟框架(jmockit)的人为示例。输出为:
原始私有方法
其他方法
新的私有方法
其他方法
public static void main(String[] args) {
A a = new A(); //prints Original private method
a.m2(); //prints Some other method
new MockUp<A>() {
@Mock
public void m() {
System.out.println("New private method");
}
};
A b = new A(); //prints New private method
b.m2(); //prints Some other method
}
static class A {
public A() {
m();
}
private void m() {
System.out.println("Original private method");
}
public void m2() {
System.out.println("Some other method");
}
}
您可以使用AspectJ来访问私有方法:
public privileged aspect SomeClassExposerAspect {
void around(SomeClass obj) : execution(private void badCall()) {
try {
// use privileged access to return the private member
((Example )obj).badCall();
}
// safeguard against unexpected 3rd party library versions, if using load-time weaving
catch (NoSuchMethodError e) {
//log something
}
}
}
}
如果你有源代码,我建议你"修补"类。
编译并构建修改后的版本,并替换jar中的旧版本或者在类路径的前面添加它,这样它就会隐藏旧版本。
顺便说一句:您甚至可以用这种方式在JVM中修补类,尽管这很少是一个好主意。div;)