浅析JAVA反射(二)

上一篇介绍了java反射的基本概念,并通过一个简单的例子展示了如何获取一个类所定义的变量和方法
下面将介绍如何通过反射来访问类里面的方法,先看一个例子

  1. import java.lang.reflect.AccessibleObject;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. public class Test {
  5.     private String name;
  6.     
  7.     public String getName() {
  8.         return name;
  9.     }
  10.     public void setName(String name) {
  11.         this.name = name;
  12.         System.out.println("初始化name属性:"+name);
  13.     }
  14.     public static void main(String[] args) {
  15.         System.out.println("show方法的输出:");
  16.         show(new Test());
  17.         System.out.println("getSetMethod方法的输出:");
  18.         getSetMethod(new Test());
  19.     }
  20.     @SuppressWarnings("unchecked")
  21.     public static void show(Object clazz){
  22.         try {
  23.             /**
  24.              * 获取类里面的setName方法 并指定其参数是String类型
  25.              */
  26.             Method setName=clazz.getClass().getMethod("setName"new Class[]{String.class});
  27.             /**
  28.              * 调用setName方法,并指定参数为"zhjb"
  29.              */
  30.             setName.invoke(clazz, "zhjb");
  31.             
  32.             /**
  33.              * 获取类里面的getName方法 
  34.              */
  35.             Method getName=clazz.getClass().getMethod("getName");
  36.             /**
  37.              * 调用getName方法,并打印其返回值
  38.              */
  39.             System.out.println(getName.invoke(clazz));
  40.             
  41.         } catch (Exception e) {
  42.             e.printStackTrace();
  43.         }
  44.     }
  45.     @SuppressWarnings("unchecked")
  46.     public static void getSetMethod(Object clazz){
  47.         try {
  48.             /**
  49.              * 得到定义的变量
  50.              */
  51.             Field[] field=clazz.getClass().getDeclaredFields();
  52.             /**
  53.              * 设置访问权限,即使是private也能访问
  54.              */
  55.             AccessibleObject.setAccessible(field, true);
  56.             /**
  57.              * 给该变量赋值
  58.              */
  59.             field[0].set(clazz, "zhjb");
  60.             
  61.             System.out.println(field[0].get(clazz));
  62.         } catch (Exception e) {
  63.             e.printStackTrace();
  64.         }
  65.     }
  66. }

运行上面的代码输出结果为:

show方法的输出:
初始化name属性:zhjb
zhjb
getSetMethod方法的输出:
zhjb

由输出的结果可以看出,show方法里面通过调用类里面的set方法给变量name赋值,而getSetMethod方法里面是直接对类里面成员变量赋值,应为 AccessibleObject.setAccessible(field, true);这样设置了访问权限,那么即使是private 也能进行直接的赋值,但是这种方法并不是很好,破坏了JavaBean的规则,所以建议使用通过get 、set的方法来访问Java类。上面的例子都写了注释了,就不在细说了。

下面看一个例子,就是把request里面的参数根据名字封装到一个JavaBean里面

 

  1. /**
  2.      * 把request对象里面的属性拷贝到一个标准的JavaBean里面,时间格式默认为yyyy-MM-dd HH:mm:SS
  3.      * 因为只是介绍反射的用法,所以本方法只是做演示,肯定有很多的BUG,Object 里面的属性没有自己定义的类
  4.      * 如果实际工程中可以使用org.apache.commons.beanutils.BeanUtils.copyProperties()方法
  5.      * @param obj
  6.      * @param request
  7.      * @throws ParseException 
  8.      */
  9.     @SuppressWarnings("unchecked")
  10.     public static void copyProperties(Object obj,HttpServletRequest request) throws Exception{
  11.         /**
  12.          * 得到定义的变量
  13.          */
  14.         Field[] field=obj.getClass().getDeclaredFields();
  15.         Class[] clazz =new Class[1];
  16.         for(Field f:field){
  17.             Object value =request.getParameter(f.getName());
  18.             if(value==null){
  19.                 continue;
  20.             }
  21.             String methodName=getMethodName(f.getName());
  22.             
  23.             if(f.getType().getName().equals("java.util.Date")){
  24.                 SimpleDateFormat sf= new SimpleDateFormat("yyyy-MM-dd HH:mm:SS");
  25.                 value=sf.parse(value.toString());
  26.                 clazz[0]=Date.class;
  27.             }else if(f.getType().getName().equals(Integer.class.getName())){
  28.                 clazz[0]=Integer.class;
  29.                 value=new Integer(value.toString());
  30.             }else if(f.getType().getName().equals(String.class.getName())){
  31.                 clazz[0]=String.class;
  32.             }
  33.             Method method=obj.getClass().getDeclaredMethod(methodName, clazz);
  34.             method.invoke(obj, value);
  35.         }
  36.     }
  37.     /**
  38.      * 把属性的第一个字母变为大写,然后在前面加上set,给该属性赋值,这是JavaBean的标准命名规则
  39.      * @param fieldName
  40.      */
  41.     public static String getMethodName(String fieldName){
  42.         char c=fieldName.charAt(0);
  43.         if(c>='a'&&c<='z'){
  44.             c=(char)(c-'a'+'A');
  45.         }
  46.         return "set"+c+fieldName.substring(1);
  47.     }

注:Java里面的属性必须是对象,有代码就可以去看如何实现了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值