A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 邱峁 中级黑马   /  2012-11-29 15:43  /  1467 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

怎么理解成员变量反射啊
我在什么情况下用啊

4 个回复

倒序浏览
本帖最后由 yunhaitian 于 2012-11-29 15:59 编辑

成员变量反射,就是拿到该成员变量在内存中的字节码。而使用时候就是改变了内存中的字节码,相当于临时改变了加载进内存的程序(个人理解)。
回复 使用道具 举报
哦。。。
回复 使用道具 举报
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 是用来描述某个类中单个方法的一个类。

评分

参与人数 1技术分 +1 收起 理由
杨千里 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
应用背景
假设我们有一个可以运行的程序,我们想要扩展它的功能,可是我们不能获得他的源代码。该怎么办呢?程序对外提供了一个接口,我们可以提供一个实现该接口的扩展功能类,那么要怎么让程序使用这个类呢?这就用到了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()

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马