使用反射来修改对象的结构

时间:2013-12-28 16:57:18

标签: java reflection

来自wikipedia

  

反射是计算机程序在运行时检查和修改对象的结构和行为(特别是值,元数据,属性和函数)的能力。

有人能给我一个修改对象结构的具体例子吗?我知道以下示例。

Object foo = Class.forName("complete.classpath.and.Foo").newInstance();
Method m = foo.getClass().getDeclaredMethod("hello", new Class<?>[0]);
m.invoke(foo);

获取课程和检查结构的其他方法。但问题是修改是如何完成的?

4 个答案:

答案 0 :(得分:2)

自从之前的答案和评论回答有关反思的问题以来,只是另外一个提示。 要真正更改类的结构,并因此在运行时更改其行为,请查看字节代码instrumentaion,在本例中为javassist和asm libs。无论如何,这不是一件轻而易举的事。

此外,您可能会看一下方面编程技术,它可以增强具有某些功能的方法。通常用于引入日志记录而不需要在类中具有日志记录类的依赖性,也不需要在问题相关代码之间调用日志记录方法。

答案 1 :(得分:2)

在英语中,反射意味着&#34;镜像&#34;。

所以我不同意维基百科的定义。对我来说,反思是关于代码的运行时检查,而不是操作。

在java中,您可以使用字节代码操作在运行时修改字节码。一个众所周知的图书馆和广泛使用的是CGLIB.

答案 2 :(得分:1)

在java中,不完全支持维基百科所定义的反射。

只有Field.setAccessible(true)Method.setAccessible(true)才能真正修改某个类,但它只会改变安全性,而不会改变行为。

像以下一样的框架hibernate使用它来通过例如向类添加行为。在字节码中生成一个子类,用于访问父类中的私有字段。

Java仍然是一种静态类型语言,与javascript不同,您可以在运行时更改任何行为。

答案 3 :(得分:1)

反射(java.lang.reflect)中修改对象类行为的唯一方法是更改​​构造函数,方法和字段的可访问性标志 - setAccessible,无论wiki说什么。虽然有像http://ru.wikipedia.org/wiki/Byte_Code_Engineering_Library这样的库用于分解,修改和重构二进制Java类