.class的程序化操作(java反射机制)

来源:互联网 发布:福州临床数据分析员 编辑:程序博客网 时间:2024/05/20 16:41

        简述:java语言是通过类装载器把Class文件装载到JVM中,而Class文件装载后在JVM中将形成一份描述class结构的元信息对象。我们可以通过该对像获取class文件的结构信息,如:构造函数、方法、属性等信息。从而我们就能够以程序化的方式对Class对象功能进行间接的调用,下面我们将逐步的说明对class对象的程序化操作。

 一、应用实例说明

 我们将通过一个用户实体类的信息装载开始探讨反射机制的应用。下面的User有构造方法、属性、方法组成,如图:1-1所示

package com.youfuo.domain;import java.io.Serializable;public class User implements Serializable {   //默认构造函数    public User(){};    //带参数构造函数    public User(String sex,String address){        System.out.println("性别:"+sex +"   地址:"+address);    }    private int age;    //用户名    private String username;    //密码    private String password;    //打印用户信息    public void printU(){        System.out.println("username:"+username +"     password:"+ password);    }    //测试private方法能不能访问    private void printPr(){        System.out.println("private大哥今年:"+age);    }     //各属性的set/get方法 自己加上去}
正常情况下我将将通过如下代码创建和调用User实例

User user = new User();user.setUsername("张三");user.setPassword("1");//调用打印方法user.printU();//因为是private所以调用不到//user.printPu();
下面我们将通过反射机会的方法程序化调用来实现:

import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import com.youfuo.domain.User;public class UserTest {        public void loadUser() throws Throwable{            //在当前线程中,获取当前的类装载器            ClassLoader loader = Thread.currentThread().getContextClassLoader();                        //通过类装载器loader加载User的反射对象(对象名必须为全路径实例名),如下所示            Class<?> clazz = loader.loadClass("com.youfuo.domain.User");                        //获取默认构造函数            Constructor<?> cons = clazz.getDeclaredConstructor((Class[])null);            //带参数的构造函数            //Constructor<?> cons2 = clazz.getDeclaredConstructor(String.class,String.class);            //cons2.newInstance("男","浙江");                        //通过构造函数的newInstance方法实例化User对象(相当于:new User())            User user = (User)cons.newInstance();                        //通过反射对象clazz的getMethod方法获取目标对象的setXxx方法            //clazz.getMethod(name, parameterTypes),name为目标对象的方法名,            //parameterTypes为方法参数的类型            Method setUsername = clazz.getMethod("setUsername", String.class);             //通过invoke调用上面获取到的方法setXxx            //setUsername.invoke(obj, args),obj为操作的实例化对象,args为            //实例化对象的参数            setUsername.invoke(user, "张三");                        Method setPassword = clazz.getMethod("setPassword", String.class);            setPassword.invoke(user, "1");                        //获取所有的对象信息            //Field field[] = clazz.getDeclaredFields()                        //通过反射对象clazz的getDeclaredField方法获取对象属性            Field ageField = clazz.getDeclaredField("age");            //取消java语言的访问检查,这样就可以访问private、protected的属性            ageField.setAccessible(true);            ageField.set(user, 18);                        Method pr = clazz.getDeclaredMethod("printPr", (Class[])null);            //取消java语言的访问检查,这样就可以访问private、protected的方法            pr.setAccessible(true);            pr.invoke(user, (Object[])null);                }        public static void main(String args[]) throws Throwable{        System.out.println("测试");         new UserTest().loadUser();    }}

二、反射应用类的说明

     下面将对用到的Constructor、Method、Field三个类做简要的说明

      1.Constructor类是针对反射机制中的构造函数的,我们可以通过Class中的getConstructors方法获取.class对象中的所有构造方法数组,当然我们也可以通过getDeclaredConstructor方法获取指定的构造函数等等,而Constructor的主要方法是newInstance方法,通过该方法我们可以实例化对象,就像new User()一样。

      2.Method类是针对反射机制中的方法,我们可以通过Class中的getDeclaredMethods方法获取.class对象中的所有方法的数据,也可以通过getMethod、getDeclaredMethod方法获取指定的方法等等,而Method的主要方法是invoke,通过该方法我们往指定实例对象注入值。

     3.Field类是针对反射机制中的成员变量的,我们可以通过Class中的getDeclaredFields方法获取所有.class对象中的属性,也可以通过getDeclaredField方法获取指定的属性,而Field的主要方法是set,我们可以通过对指定的属性注入值。

三、类装载器说明

      类装载器JVM自带有RootClassLoader、ExtClassLoader、AppClassLoader三个;

      1.RootClassLoader为根装载器,负责加载jre核心类库的,是jvm最优化查找类的地方

      2.ExtClassLoader为扩展类库加载器,负责加载jre目录ext目录中的类库,是jvm次优化查找类的地方

      3.AppClassLoader为加载当前目录classpath目录下的类库,为默认查找类的地方


(纠结了好久是不是要写些啥呢,花了两个小时终于写出来了,哈哈。。。下篇应该是写关于struts1.2.x通过反射技术对DispatchAction类的扩展)



原创粉丝点击