【问题标题】:How to change method behaviour through reflection?如何通过反射改变方法行为?
【发布时间】:2013-04-12 08:38:31
【问题描述】:

我在一些遗留代码中有一个静态方法,它被多个客户端调用。我显然没有选择覆盖它,或者通过依赖注入改变行为。我不允许修改现有的类。

我现在要做的是使用反射来改变行为(该方法 - 具有相同的签名和返回类型)。

有可能吗?如果没有,任何设计模式都可以救我吗?

谢谢!

编辑:我可以更改/修改什么有些混乱。我无法更改任何现有的类/方法 - 但我可以向项目添加更多类。我能对现有类做的最好的事情就是注释它们。这样做是为了避免破坏现有代码中的任何内容——这意味着对一个大项目进行完整的一轮测试。

编辑 2:java.lang.Instrumentation 不适用于 Android - 否则听起来很合适!

【问题讨论】:

  • 不允许修改,但允许通过反射修改?这似乎风险更大。
  • 我认为这将成为一场维护噩梦。代码将撒在任何阅读它的人身上。去获得批准以更改该课程。
  • @SpaceTrucker :我知道这很棘手——我们有机制来提醒未来的团队。这就是我获得批准的原因。
  • AOP,面向方面的编程可以做到这一点,包装它的调用。
  • 在任何情况下您的行为都会发生变化,这需要进行测试。所以测试工作总是一样的。唯一的问题是您如何实施该更改。

标签: java android design-patterns legacy-code


【解决方案1】:

听起来是个奇怪的要求……

无论如何,反射不允许你改变代码行为,它只能探索当前代码,调用方法和构造函数,改变字段值,诸如此类。

如果您想真正改变方法的行为,您必须使用字节码操作库,例如 ASM。但这不会很容易,可能不是一个好主意……

可能对您有所帮助的模式:

  • 如果类不是最终类,并且您可以修改客户端、扩展现有类并重载方法,使其具有您想要的行为。编辑:只有在方法不是静态的情况下才有效!
  • 方面编程:使用 AspectJ 将拦截器添加到方法中

无论如何,最合乎逻辑的做法是找到修改现有类的方法,变通办法只会使您的代码更加复杂和难以维护。

祝你好运。

【讨论】:

  • 静态方法不能被覆盖。我想知道反射是否可以改变字段值,为什么不能改变方法!
  • 我是 AOP 新手。现在探索它!
  • 你说的当然是静态的方法是对的。我相应地编辑了我的答案。
【解决方案2】:

我想你可以看看Instrumentation 类,它有一个方法redefineClasses(ClassDefintion classDefinition)

重新定义可能会改变方法体、常量池和属性。重新定义不得添加、删除或重命名字段或方法,更改方法的签名或更改继承。

希望这会有所帮助。

参考:Javadoc

【讨论】:

  • 抱歉,忘记添加这是Android。我没有这门课可以使用:(
猜你喜欢
  • 2018-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多