反射技术总结

所有的框架和服务器开发都是用的反射技术,学好反射对日后更深层次的开发是非常重要的。

通过反射可以动态的获取类的成员,在不想改动源代码的情况下修改类,这样我们就可以通过反射技术将这个类加载进来。我们在框架用xml文件进行配置的时候,实际上就是获取到类名使用反射动态的加载进来,大大提高了可扩展性,另外再访问私有属性的时候是访问不到的,因为它不可见,如果非要访问的话可以用暴力反射进行访问

实例:

  1. /* 
  2.  * 执行字节码文件中一个方法。 
  3.  */  
  4. private static void getSingleMethod() throws ClassNotFoundException, Exception, Exception {  
  5.     Class clazz = Class.forName("cn.test.demo.Person");  
  6.     //指定要运行的方法  
  7.     Method method = clazz.getMethod("show2"null);  
  8.     //调用此方法并运行  
  9.     method.invoke(clazz.newInstance(), null);  
  10. }  
  11.   
  12. /* 
  13.  * 当动态加载的类中的没有空参数构造函数时。 
  14.  * 需要获取指定的构造函数进行该字节码文件对象的初始化。 
  15.  */  
  16. private static void getConstructor() throws Exception {  
  17.     Class clazz = Class.forName("cn.test.demo.Person");  
  18.     //获取到指定参数类型的构造函数对象。  
  19.     Constructor constructor = clazz.getConstructor(String.class);  
  20.     //通过构造器创建该类的实例  
  21.     Person p = (Person)constructor.newInstance("zhangan");  
  22.     //获取要调用的方法  
  23.     Method method = clazz.getMethod("show",int.class);  
  24.     //执行方法,获取返回值  
  25.     String str = (String)method.invoke(p, 88);  
  26.     System.out.println("str="+str);  
  27. }  
  28.   
  29. /* 
  30.  * 获取指定类中的方法。 
  31.  */  
  32. private static void getClassMethod() throws ClassNotFoundException {  
  33.     Class clazz = Class.forName("cn.test.demo.Person");  
  34.     //获取包括父类的方法,只能获取共有的方法  
  35.     Method[] methods = clazz.getMethods();  
  36.     //不能获取父类的方法可以获取指定类的私有和共有的方法  
  37.     methods = clazz.getDeclaredMethods();  
  38.     for(Method m : methods){  
  39.         System.out.println(m.toString());  
  40.     }  
  41. }  
  42.   
  43. /* 
  44.  * 获取字节码文件对象的三种方式 
  45.  */  
  46. private static void demoGetClass() throws ClassNotFoundException {  
  47.       
  48.     //方式一,getClass();  
  49.     Person p = new Person();  
  50.     Class clazz = p.getClass();  
  51.     System.out.println(clazz.getName());  
  52.       
  53.     //方式二,每一个类都有一个属性 .class.  
  54.     Class c2 = Person.class;  
  55.     System.out.println(c2.getName());  
  56.       
  57.     //方式三,通过Class类中的一个static方法forName获取一个字节码文件对象。  
  58.     //给forName传值必须是类的全名称。  
  59.     Class c3 = Class.forName("cn.test.demo.Person");  
  60.     System.out.println(c3.getName());  
  61. }  

Person.java:

  1. public class Person {  
  2.   
  3.     private String name;  
  4.     public Person(){  
  5.         System.out.println("person run");  
  6.     }  
  7.     public Person(String name){  
  8.         this.name =name;  
  9.         System.out.println("-------------");  
  10.     }  
  11.       
  12.     public String show(int num){  
  13.         System.out.println("num="+num+"--show run--"+name);  
  14.         return "hahha";  
  15.     }  
  16.       
  17.     public void show2(){  
  18.         System.out.println("------123-------");  
  19.     }  
  20.     public void haha(String s){  
  21.         System.out.println("haha="+s);  
  22.     }  
  23.     private void function(){  
  24.         System.out.println("functio run");  
  25.     }  
  26. }  

总结:

1.加载类的三种方式:

  1. //加载类方法1:  
  2. String classname ="cn.itcast.bean.Person";  
  3. Class clazz1=Class.forName(classname); //获取类的字节码拿到类  
  4.   
  5. //加载类方法2:  
  6. Class clazz2=Person.class;  //在框架中用的不多  
  7.   
  8. //加载类方法3:  
  9. Class clazz3=new Person().getClass();  


 

2.反射构造方法创建类的实例:

构造函数有四种方式:无参、有参、多个参数、私有构造函数。

  1. public Person(){}  
  2.   
  3. public Person(String name){  
  4.     this.name=name;  
  5. }  
  6. public Person(String name,List list){  
  7.       
  8. }  
  9. private Person(Set set){  
  10.       
  11. }  


        针对以上四种构造方法的反射如下:

  1. //反射无参的构造函数  
  2. @Test  
  3. public void test2 () throws Exception{  
  4.     String classname ="cn.itcast.bean.Person";  
  5.     Class clazz1=Class.forName(classname);  //加载类  
  6.     Constructor c=clazz1.getConstructor(null);//拿到无参的构造函数  
  7.     Object obj =c.newInstance(null);    //创建实例对象  
  8.     System.out.println(obj);  
  9. }  
  10. //反射有参的构造函数  
  11. @Test  
  12. public void test3 () throws Exception{  
  13.     String classname ="cn.itcast.bean.Person";  
  14.     Class clazz1=Class.forName(classname);   
  15.     Constructor c=clazz1.getConstructor(String.class);//拿到有参的构造函数  
  16.     Object obj =c.newInstance("aaa");   //创建实例对象  
  17.     System.out.println(obj);  
  18. }  
  19. //反射有多个参数的构造函数  
  20. @Test  
  21. public void test4 () throws Exception{  
  22.     String classname ="cn.itcast.bean.Person";  
  23.     Class clazz1=Class.forName(classname);   
  24.     Constructor c=clazz1.getConstructor(String.class,List.class);//拿到多个参数的构造函数  
  25.     Object obj =c.newInstance("bbb",new ArrayList());     
  26.     System.out.println(obj);  
  27. }  
  28. //反射私有的构造函数  
  29. @Test  
  30. public void test5 () throws Exception{  
  31.     String classname ="cn.itcast.bean.Person";  
  32.     Class clazz1=Class.forName(classname);   
  33.     Constructor c=clazz1.getDeclaredConstructor(Set.class);//得到类里面声明的成员  
  34.     c.setAccessible(true);      //暴力反射  
  35.     Object obj =c.newInstance(new HashSet());     
  36.     System.out.println(obj);  
  37. }  

 

3.反射方法:

          方法共有五几种形态:

  1. public void a1(){  
  2.     System.out.println("hahaa");  
  3. }  
  4.   
  5. public void a2(String name){  
  6.     System.out.println(name);  
  7. }  
  8.   
  9. public String a3(String name ,String password){  
  10.     return name+password;  
  11. }  
  12.   
  13. private String a4(List list){  
  14.     return list.toString();  
  15. }  
  16.   
  17. private static void a5(String arr[]){  
  18.     System.out.println(Arrays.asList(arr));  
  19. }  

 
            针对五种形态的反射方法如下:

  1. //反射无参方法  
  2. @Test  
  3. public void test1() throws Exception{  
  4.     Person  p=new Person();  
  5.     Class clazz=Class.forName("cn.itcast.bean.Person");//拿到类  
  6.     Method m=clazz.getMethod("a1",null);    //反射无参数的构造方法  
  7.     m.invoke(p,null);   //执行无参构造方法  
  8. }  
  9. //反射一个参数的方法  
  10. @Test  
  11. public void test2() throws Exception{  
  12.     Person  p=new Person();  
  13.     Class clazz=Class.forName("cn.itcast.bean.Person");  
  14.     Method m=clazz.getMethod("a2",String.class);    //反射有参数的构造方法  
  15.     m.invoke(p,"aaaaa");      
  16. }  
  17. //反射多个参数的方法  
  18. @Test  
  19. public void test3() throws Exception{  
  20.     Person  p=new Person();  
  21.     Class clazz=Class.forName("cn.itcast.bean.Person");  
  22.     Method m=clazz.getMethod("a3",String.class,String.class);     
  23.     String result=(String) m.invoke(p,"aaaaa","bbbbbb");      
  24.     System.out.println(result);  
  25. }  
  26. //反射私有的方法  
  27. @Test  
  28. public void test4() throws Exception{  
  29.     Person  p=new Person();  
  30.     Class clazz=Class.forName("cn.itcast.bean.Person");  
  31.     Method m=clazz.getDeclaredMethod("a4",List.class);  //得到声明的方法  
  32.     m.setAccessible(true);  //暴力反射  
  33.     String result=(String) m.invoke(p,new ArrayList());   
  34.     System.out.println(result);  
  35. }   
  36. //反射私有的静态方法  
  37. @Test  
  38. public void test5() throws Exception{  
  39.     Class clazz=Class.forName("cn.itcast.bean.Person");  
  40.     Method m=clazz.getDeclaredMethod("a5",String [].class);   
  41.     m.setAccessible(true);  //暴力反射  
  42.     m.invoke(null,(Object)new String []{"1","2"});    
  43. }   


 

4.反射字段

       反射私有字段

  1. //反射私有字段  
  2. @Test  
  3. public void test1() throws Exception{  
  4.     Person p =new Person();  
  5.     Class clazz=Class.forName("cn.itcast.bean.Person");  
  6.     Field f=clazz.getDeclaredField("name"); //拿到字段  
  7.     f.setAccessible(true);  
  8.     f.set(p,"frk");     //封装值  
  9.     String name=(String) f.get(p);//得到值  
  10.     System.out.println(name);  
  11. }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值