浅析JAVA反射(二)

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

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

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

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-ddHH:mm:SS
  3. *因为只是介绍反射的用法,所以本方法只是做演示,肯定有很多的BUG,Object里面的属性没有自己定义的类
  4. *如果实际工程中可以使用org.apache.commons.beanutils.BeanUtils.copyProperties()方法
  5. *@paramobj
  6. *@paramrequest
  7. *@throwsParseException
  8. */
  9. @SuppressWarnings("unchecked")
  10. publicstaticvoidcopyProperties(Objectobj,HttpServletRequestrequest)throwsException{
  11. /**
  12. *得到定义的变量
  13. */
  14. Field[]field=obj.getClass().getDeclaredFields();
  15. Class[]clazz=newClass[1];
  16. for(Fieldf:field){
  17. Objectvalue=request.getParameter(f.getName());
  18. if(value==null){
  19. continue;
  20. }
  21. StringmethodName=getMethodName(f.getName());
  22. if(f.getType().getName().equals("java.util.Date")){
  23. SimpleDateFormatsf=newSimpleDateFormat("yyyy-MM-ddHH:mm:SS");
  24. value=sf.parse(value.toString());
  25. clazz[0]=Date.class;
  26. }elseif(f.getType().getName().equals(Integer.class.getName())){
  27. clazz[0]=Integer.class;
  28. value=newInteger(value.toString());
  29. }elseif(f.getType().getName().equals(String.class.getName())){
  30. clazz[0]=String.class;
  31. }
  32. Methodmethod=obj.getClass().getDeclaredMethod(methodName,clazz);
  33. method.invoke(obj,value);
  34. }
  35. }
  36. /**
  37. *把属性的第一个字母变为大写,然后在前面加上set,给该属性赋值,这是JavaBean的标准命名规则
  38. *@paramfieldName
  39. */
  40. publicstaticStringgetMethodName(StringfieldName){
  41. charc=fieldName.charAt(0);
  42. if(c>='a'&&c<='z'){
  43. c=(char)(c-'a'+'A');
  44. }
  45. return"set"+c+fieldName.substring(1);
  46. }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值