黑马程序员技术交流社区
标题:
反射
[打印本页]
作者:
邱峁
时间:
2012-11-29 15:43
标题:
反射
怎么理解成员变量反射啊
我在什么情况下用啊
作者:
冯盼
时间:
2012-11-29 15:57
本帖最后由 yunhaitian 于 2012-11-29 15:59 编辑
成员变量反射,就是拿到该成员变量在内存中的字节码。而使用时候就是改变了内存中的字节码,相当于临时改变了加载进内存的程序(个人理解)。
作者:
邱峁
时间:
2012-11-29 17:07
哦。。。
作者:
黑马-王宁
时间:
2012-11-29 18:06
Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性。例如,使用它能获得 Java 类中各成员的名称并显示出来。 Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。
JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。
1. 一个简单的例子
考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。
1.import java.lang.reflect.*;
2.
3.public class DumpMethods {
4. public static void main(String args[]) {
5. try {
6. Class c = Class.forName("java.util.Stack");
7.
8. Method m[] = c.getDeclaredMethods();
9.
10. for (int i = 0; i < m.length; i++)
11. System.out.println(m[i].toString());
12. }
13. catch (Throwable e){
14. System.err.println(e);
15. }
16. }
17.}
它的结果输出为:
1.public synchronized java.lang.Object java.util.Stack.pop()
2.public java.lang.Object java.util.Stack.push(java.lang.Object)
3.public boolean java.util.Stack.empty()
4.public synchronized java.lang.Object java.util.Stack.peek()
5.public synchronized int java.util.Stack.search(java.lang.Object)
这样就列出了java.util.Stack 类的各方法名以及它们的限制符和返回类型。
这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。
作者:
孟伟娟
时间:
2012-11-29 19:07
应用背景
假设我们有一个可以运行的程序,我们想要扩展它的功能,可是我们不能获得他的源代码。该怎么办呢?程序对外提供了一个接口,我们可以提供一个实现该接口的扩展功能类,那么要怎么让程序使用这个类呢?这就用到了java反射机制。
应用程序会对外提供一个配置文件,我们把这个扩展功能类的类名写到配置文件中,则应用程序会自动读取配置文件,并找到相应的类,执行扩展功能。
过程就是:加载类;创建类对象;调用类中的内容。
而这个过程就是java反射机制所做的内容。
Java反射机制的好处就是可以提供程序的扩展性。
import java.lang.reflect.*;
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
accessField();
}
private static void accessField() throws Exception {
//先获取Class对象
String className = "reflect.Person";
Class clazz = Class.forName(className);
//获取字段
//获取公有,私有,保护,包访问字段,不可访问继承的字段
Field field = clazz.getDeclaredField("age");
System.out.println(field);
//给字段设置值
Object obj = clazz.newInstance();
field.set(obj, 19);
System.out.println(field.get(obj));
}
}/*Output:
int reflect.Person.age
new Person()
19
*/
上例是获得成员变量,即字段的方法。
获取字段的方法有getMethods():获取公有和父类中的方法
getDeclaredMethods():获取本类中,包括私有的方法
getMethod(String methodName,para):获取公有和父类中的方法,传入方法名称和参数
getDeclaredMethods(String methodName,para):获取本类中,包括私有的指定方法名称和传入参数的方法
获取方法对象invoke(Object obj,para)
注意:如果获取的方法是私有的话,不能访问它,解决办法是:AccessibleObject类中有setAccessible(boolean flag)
方法,设为true时,可以取消访问权限,对私有方法进行访问。但也不建议这么做。
访问静态方法:
静态方法不需要创建对象,假设有一个静态的method的空参数方法。
Method method = clazz.getDeclaredMethod("method", null);
method.invoke(null, null);
这样就可以直接取出静态的方法名:method()
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2