当前位置: 首页 > 知识库问答 >
问题:

如何通过反射改变方法行为?

弘康安
2023-03-14

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

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

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

谢谢

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

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

共有2个答案

全丰
2023-03-14

我想您可以看看Instrumentation类,它有一个方法重定义类(classdefination classDefinition)

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

希望这有帮助。

参考文献:Javadoc

金阳曜
2023-03-14

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

无论如何,反射不允许您更改代码行为,它只能探索当前代码、调用方法和构造函数、更改字段值等等。

如果您想要实际更改方法的行为,您必须使用字节码操纵库,如ASM。但这并不容易,可能不是个好主意。。。

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

  • 如果类不是final,并且您可以修改客户机,则扩展现有类并使用所需的行为重载该方法。编辑:只有在方法不是静态的情况下才有效

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

祝你好运

 类似资料:
  • 主要内容:判定及获取元素的相关方法,值修改相关方法,值可修改条件之一:可被寻址,值可修改条件之一:被导出Go语言中类似 x、x.f[1] 和 *p 形式的表达式都可以表示变量,但是其它如 x + 1 和 f(2) 则不是变量。一个变量就是一个可寻址的内存空间,里面存储了一个值,并且存储的值可以通过内存地址来更新。 对于 reflect.Values 也有类似的区别。有一些 reflect.Values 是可取地址的;其它一些则不可以。考虑以下的声明语句: x := 2 // value type

  • 要 动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 类型的对象或者数组。 getMethods() getMethods(String name,Class<?> …parameterTypes) getDeclaredMethods() getDeclaredMethods(String name,Class<?>...parameterTypes) 如果是访问指定的构造方法,需要

  • 问题内容: 我有一个对象,我想知道它的返回类型是否为。 我已经检查了Javadocs,并且有一个返回Class对象的方法。问题是,如果方法无效,他们不会说返回类型是什么。 谢谢! 问题答案: 快速样本:

  • 问题内容: 只是玩弄Java反射,我想我大部分时间都掌握了它。我从这个问题/答案中了解到,在大多数情况下,我仅限于静态变量。如果我有该类的实例,则可以访问非静态变量,这确实有意义,我得到了很多。 说我有以下两节课: 我知道如何访问,这不是问题。我的理解是,我能得到的同样的方式(即)。从其他研究(javadocs,trails等)中,我收集到需要一个实例才能获得的值。 所以我的问题; 由于是静态的,

  • 为了能够 动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 类型的对象或者数组。 getConstructors() getConstructor(Class<?>…parameterTypes) getDeclaredConstructors() getDeclaredConstructor(Class<?>...parameterTypes) 如果是访问指定的构造方法,需要根据该构

  • 如何使用反射来区分类重载方法,例如: <代码>方法()和<代码>方法(int-arg) 并调用此函数: 它返回错误,这意味着默认情况下选择没有参数的方法。如果我调用没有int参数的方法,它将工作。我问如何区分重载的方法?我已经阅读了的文档https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html还有一个关于SO的旧帖子,但两个来源都