Java学习之反射机制笔记--4
2016-05-19 11:47
573 查看
4、Java反射机制深入研究
1)通过反射调用类中的方法
在正常情况下,一个类的对象产生后,就可以调用这个类的方法;如果要调用的话,则必须要知道要调用的方法名是什么,之后通过Class类的getMethod()方法,得到一个Method对象,之后调用Method对象来执行此方法,但是,在调用方法的时候,会牵扯到方法中的参数问题,所以通过getMethod得到的对象,必须设置好需要的参数类型
作者:李兴华,国籍:China
调用sayChina方法,执行调用的是invoke方法,执行的时候,还需要传递参数进去,而且需要实例化对象
如果要调用的方法中有参数,则必须设置参数的类型及内容
2)通过反射调用类中的setter和getter
setter和getter是标准的属性访问方法,如果一个类的属性被封装,则必须通过setter和getter方法设置和取得,实际上此方法的操作之所以这样规定,主要是由于反射机制给予支持造成的。
通过反射,可以调用setter和getter
如果想调用setter,例如name属性设置,即setName()方法写,方法的第二个单词的首字母要大写,
年龄:30
3)通过反射操作属性
如果要操作一个类中的属性,则可以通过getField()来完成
在访问私有属性的时候,必须让属性可见,设置属性可见---属性.setAccessible(true)
4)通过反射操作数组
反射不光可以应用在类上,也可以应用在任何引用数据类型上,包括数组,数组使用Array类完成
Class类中存在一个方法:getComponentType()返回一个数组
得到数组指定下标的内容Array.get(Object arr,int index)
修改数组指定下标的内容Array.get(Object arr,int index)
开辟新数组Array.newInstance(Class<?> componentType, int length)
取得数组信息并修改内容
长度:3
第一个内容:1
第一个内容:6
使用Array类还可以修改数组大小
修改的内容其实就是开辟一个新的工程,还要把旧的内容拷贝到新的数组之中去
1、2、3、0、0、
-------------------------
java.lang.String数组的长度是:8
hello、world、Java、null、null、null、null、null、
1)通过反射调用类中的方法
在正常情况下,一个类的对象产生后,就可以调用这个类的方法;如果要调用的话,则必须要知道要调用的方法名是什么,之后通过Class类的getMethod()方法,得到一个Method对象,之后调用Method对象来执行此方法,但是,在调用方法的时候,会牵扯到方法中的参数问题,所以通过getMethod得到的对象,必须设置好需要的参数类型
package com.reflection.demo4; import java.lang.reflect.Method ; public class InvokeSayChinaDemo{ public static void main(String args[]){ Class<?> c1 = null ; try{ c1 = Class.forName("com.reflection.demo4.Person") ; // 实例化Class对象 }catch(Exception e){} try{ Method met = c1.getMethod("sayChina") ; // 找到sayChina()方法 met.invoke(c1.newInstance()) ; // 调用方法 }catch(Exception e){ e.printStackTrace() ; } } };
作者:李兴华,国籍:China
调用sayChina方法,执行调用的是invoke方法,执行的时候,还需要传递参数进去,而且需要实例化对象
如果要调用的方法中有参数,则必须设置参数的类型及内容
package com.reflection.demo4; import java.lang.reflect.Method ; public class InvokeSayHelloDemo{ public static void main(String args[]){ Class<?> c1 = null ; try{ c1 = Class.forName<span style="font-family:SimSun;">("com.reflection.demo4.Person") ; // 实例化Class对象</span> }catch(Exception e){} try{ Method met = c1.getMethod("sayHello",String.class,int.class) ; // 找到sayChina()方法 String rv = null ; rv = (String)met.invoke(c1.newInstance(),"李兴华",30) ; // 调用方法 System.out.println(rv) ; }catch(Exception e){ e.printStackTrace() ; } } };李兴华,你好!我今年:30岁了!
2)通过反射调用类中的setter和getter
setter和getter是标准的属性访问方法,如果一个类的属性被封装,则必须通过setter和getter方法设置和取得,实际上此方法的操作之所以这样规定,主要是由于反射机制给予支持造成的。
通过反射,可以调用setter和getter
如果想调用setter,例如name属性设置,即setName()方法写,方法的第二个单词的首字母要大写,
package com.reflection.demo4; import java.lang.reflect.Method ; public class InvokeSetGetDemo{ public static void main(String args[]){ Class<?> c1 = null ; Object obj = null ; try{ c1 = Class.forName("com.reflection.demo4.Person") ; // 实例化Class对象 }catch(Exception e){} try{ obj = c1.newInstance() ; }catch(Exception e){} setter(obj,"name","李兴华",String.class) ; // 调用setter方法 setter(obj,"age",30,int.class) ; // 调用setter方法 System.out.print("姓名:") ; getter(obj,"name") ; System.out.print("年龄:") ; getter(obj,"age"); } /** Object obj:要操作的对象 String att:要操作的属性 Object value:要设置的属性内容 Class<?> type:要设置的属性类型 */ public static void setter(Object obj,String att,Object value,Class<?> type){ try{ Method met = obj.getClass().getMethod("set"+initStr(att),type) ; // 得到setter方法 met.invoke(obj,value) ; // 设置setter的内容 }catch(Exception e){ e.printStackTrace() ; } } public static void getter(Object obj,String att){ try{ Method met = obj.getClass().getMethod("get"+initStr(att)) ; // 得到setter方法 System.out.println(met.invoke(obj)) ; // 调用getter取得内容 }catch(Exception e){ e.printStackTrace() ; } } public static String initStr(String old){ // 将单词的首字母大写方法 String str = old.substring(0,1).toUpperCase() + old.substring(1) ; return str ; } };姓名:李兴华
年龄:30
3)通过反射操作属性
如果要操作一个类中的属性,则可以通过getField()来完成
package com.reflection.demo4; import java.lang.reflect.Field ; public class InvokeFieldDemo{ public static void main(String args[]) throws Exception{ Class<?> c1 = null ; Object obj = null ; c1 = Class.forName("com.reflection.demo4.Person") ; // 实例化Class对象 obj = c1.newInstance() ; Field nameField = null ; Field ageField = null ; nameField = c1.getDeclaredField("name") ; // 取得name属性 ageField = c1.getDeclaredField("age") ; // 取得name属性 nameField.setAccessible(true) ; // 此属性对外部可见 ageField.setAccessible(true) ; // 此属性对外部可见 nameField.set(obj,"小米") ; // 设置name属性内容 ageField.set(obj,3) ; // 设置age属性内容 System.out.println("姓名:" + nameField.get(obj)) ; System.out.println("年龄:" + ageField.get(obj)) ; } };
在访问私有属性的时候,必须让属性可见,设置属性可见---属性.setAccessible(true)
4)通过反射操作数组
反射不光可以应用在类上,也可以应用在任何引用数据类型上,包括数组,数组使用Array类完成
Class类中存在一个方法:getComponentType()返回一个数组
得到数组指定下标的内容Array.get(Object arr,int index)
修改数组指定下标的内容Array.get(Object arr,int index)
开辟新数组Array.newInstance(Class<?> componentType, int length)
取得数组信息并修改内容
package com.reflection.demo4; import java.lang.reflect.Array ; public class ClassArrayDemo{ public static void main(String args[]) throws Exception{ int temp[] = {1,2,3} ;// 声明一整型数组 Class<?> c = temp.getClass().getComponentType() ; // 取得数组的Class对象 System.out.println("类型:" + c.getName()) ; // 取得数组类型名称 System.out.println("长度:" + Array.getLength(temp)) ; System.out.println("第一个内容:" + Array.get(temp,0)) ; Array.set(temp,0,6) ; System.out.println("第一个内容:" + Array.get(temp,0)) ; } };类型:int
长度:3
第一个内容:1
第一个内容:6
使用Array类还可以修改数组大小
修改的内容其实就是开辟一个新的工程,还要把旧的内容拷贝到新的数组之中去
package com.reflection.demo4; import java.lang.reflect.Array ; public class ChangeArrayDemo{ public static void main(String args[]) throws Exception{ int temp[] = {1,2,3} ;// 声明一整型数组 int newTemp[] = (int []) arrayInc(temp,5) ; // 重新开辟空间5 print(newTemp) ; System.out.println("\n-------------------------") ; String t[] = {"hello","world","Java"} ; String nt[] = (String [])arrayInc(t,8) ; print(nt) ; } public static Object arrayInc(Object obj,int len){ Class<?> c = obj.getClass() ; Class<?> arr = c.getComponentType() ; // 得到数组的Class Object newO = Array.newInstance(arr,len) ; // 开辟新的数组大小,同时指明长度 int co = Array.getLength(obj) ; System.arraycopy(obj,0,newO,0,co) ; // 拷贝从0开始内容 return newO ; } public static void print(Object obj){ // 数组输出 Class<?> c = obj.getClass() ; if(!c.isArray()){ // 判断是否是数组 return; } Class<?> arr = c.getComponentType() ; System.out.println(arr.getName()+"数组的长度是:" + Array.getLength(obj)) ; // 输出数组信息 for(int i=0;i<Array.getLength(obj);i++){ System.out.print(Array.get(obj,i) + "、") ; // 通过Array输出 } } };int数组的长度是:5
1、2、3、0、0、
-------------------------
java.lang.String数组的长度是:8
hello、world、Java、null、null、null、null、null、
相关文章推荐
- Spring mvc 自定义拦截器【详解】
- 使用maven搭建Java Web的spring MVC项目
- Execution failed for task ':xxx:packageAllDebugClassesForMul tiDex'. > java.util
- struts2 开发
- String的hashcode(java)
- Spring UT-IT
- Java GC(5)-性能调优的原则
- java读书笔记(一)
- JAVA CSA原理深度分析
- jps无法查看某个已经启动的java进程问题
- Java判断用户ip是否在指定IP段范围内
- Java线程同步
- [javaSE] 单例设计模式
- Java获取客户端/访问者真实IP地址的两种方法
- JAVA泛型
- Caused by: java.net.SocketException: Permission denied: recv failed
- 使用JAVA,实现RSA加密过程
- Java Web Filter 过滤器学习教程(推荐)
- Java中由substring方法引发的内存泄漏
- java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead