4

我想替换一个我知道源代码的类的函数。问题是我不能重写该函数,因为它是私有的,而且我不能扩展类并重写整个功能,因为错误的调用在每个可能的构造函数中。

现在我完全迷失了,我不知道如何实现所需的功能(主题化 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因此我不能简单地复制该类。

4

3 回答 3

2

这是一个使用模拟框架(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");
    }
}
于 2013-01-03T08:18:50.973 回答
2

您可以使用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
       }
   }
  }
}

这是一个关于它的好博客。

于 2013-01-03T08:24:37.600 回答
1

如果您有来源,我建议您“修补”课程。

编译并构建您的修改版本并替换 jar 中的旧版本或在类路径中更早地添加它,以便隐藏旧版本。

顺便说一句:您甚至可以通过这种方式修补 JVM 中的类,尽管这不是一个好主意。;)

于 2013-01-03T09:00:06.270 回答