来自wikipedia:
反射是计算机程序在运行时检查和修改对象的结构和行为(特别是值,元数据,属性和函数)的能力。
有人能给我一个修改对象结构的具体例子吗?我知道以下示例。
Object foo = Class.forName("complete.classpath.and.Foo").newInstance();
Method m = foo.getClass().getDeclaredMethod("hello", new Class<?>[0]);
m.invoke(foo);
获取课程和检查结构的其他方法。但问题是修改是如何完成的?
答案 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类