如何替换私有函数



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

现在我完全迷失了,我不知道如何实现所需的功能(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;)

相关内容

  • 没有找到相关文章

最新更新