天天看点

认识反射机制

认识Java反射机制

     在正常情况下,必须知道一个类才可以实例化对象,但是在Java中也通过一个对象来找到其所在的类的信息,那么这实际上是Class类的功能。

Java代码  

认识反射机制
  1. package zyz.demo;  
  2. class X{ };  
  3. public class GetClassDemo01{  
  4.     public static void main(String args[]){  
  5.         X x = new X() ; // 实例化X类的对象  
  6.         System.out.println(x.getClass().getName()) ;    // 得到对象所在的类的完整名字  
  7.     }  
  8. };     
  9.  结果:zyz.demo.X  

实例化Class类型对象

实例化Class类型对象的方法有三种:

第一种:通过forName()方法

第二种:类.class

第三种:对象.getClass()

Java代码  

认识反射机制
  1. package zyz.demo;  
  2. class X{  
  3. };  
  4. public class GetClassDemo02{  
  5.     public static void main(String args[]){  
  6.         Class<?> c1 = null ;      // 指定泛型  
  7.         Class<?> c2 = null ;      // 指定泛型  
  8.         Class<?> c3 = null ;      // 指定泛型  
  9.         try{  
  10.             // 以下的操作形式是在开发中最常用的一种形式  
  11.             c1 = Class.forName("org.lxh.demo15.getclassdemo.X") ;  
  12.         }catch(ClassNotFoundException e){  
  13.             e.printStackTrace() ;  
  14.         }  
  15.         c2 = new X().getClass() ;   // 通过Object类中的方法实例化  
  16.         c3 = X.class ;  // 通过类.class实例化  
  17.         System.out.println("类名称:" + c1.getName());// 得到类的名称  
  18.         System.out.println("类名称:" + c2.getName());// 得到类的名称  
  19.         System.out.println("类名称:" + c3.getName());// 得到类的名称  
  20.     }  
  21. };  

一旦可以实例化Class类之后,就可以进行反射的进一步操作。

1、实例化对象

Java代码  

认识反射机制
  1. <strong>class Person{  
  2.     private String name ;   // name属性  
  3.     private int age ;       // age属性  
  4.     public void setName(String name){  
  5.         this.name = name ;  
  6.     }  
  7.     public void setAge(int age){  
  8.         this.age = age ;  
  9.     }  
  10.     public String getName(){  
  11.         return this.name ;  
  12.     }  
  13.     public int getAge(){  
  14.         return this.age ;  
  15.     }  
  16.     public String toString(){   // 覆写toString()方法  
  17.         return "姓名:" + this.name + ",年龄:" + this.age  ;  
  18.     }  
  19. };  
  20. public class Demo01{  
  21.     public static void main(String args[]){  
  22.         Class<?> c = null ;       // 声明Class对象  
  23.         try{  
  24.             c = Class.forName("org.lxh.demo15.instancedemo.Person") ;  
  25.         }catch(ClassNotFoundException e){  
  26.             e.printStackTrace() ;  
  27.         }  
  28.         Person per = null ; // 声明Person对象  
  29.         try{  
  30.             per = (Person)c.newInstance() ; // 实例化对象  
  31.         }catch(Exception e){  
  32.             e.printStackTrace() ;  
  33.         }  
  34.         per.setName("李兴华") ;        // 设置姓名  
  35.         per.setAge(30) ;                // 设置年龄  
  36.         System.out.println(per) ;   // 内容输出,调用toString()  
  37.     }  
  38. };  
  39. </strong>  

     通过以上的代码,可以发现,即使不使用关键字new对象也可以进行实例化操作,反射的作用。但是,在使用以上操作的时候有一点必须注意,在操作中类中必须存在无参构造方法。否则无法实例化。

     所以说,使用以上的方法实际上还是需要类中构造方法的支持,符合于对象的实例化需求。

如果要想调用有参,由必须按照以下的步骤进行:

1、通过Class类中的getConstructors()取得本类中的全部构造方法。

2、向构造方法中传递一个对象数组进去,里面包含了构造方法中所需的各个参数。

3、之后通过Constructor实例化对象

Java代码  

认识反射机制
  1. package org.lxh.demo15.instancedemo ;  
  2. import java.lang.reflect.Constructor ;  // 导入反射机制包  
  3. class Person{  
  4.     private String name ;   // name属性  
  5.     private int age ;       // age属性  
  6.     public Person(String name,int age){  
  7.         this.setName(name) ;  
  8.         this.setAge(age);  
  9.     }  
  10.     public void setName(String name){  
  11.         this.name = name ;  
  12.     }  
  13.     public void setAge(int age){  
  14.         this.age = age ;  
  15.     }  
  16.     public String getName(){  
  17.         return this.name ;  
  18.     }  
  19.     public int getAge(){  
  20.         return this.age ;  
  21.     }  
  22.     public String toString(){   // 覆写toString()方法  
  23.         return "姓名:" + this.name + ",年龄:" + this.age  ;  
  24.     }  
  25. };  
  26. public class InstanceDemo03{  
  27.     public static void main(String args[]){  
  28.         Class<?> c = null ;       // 声明Class对象  
  29.         try{  
  30.             c = Class.forName("org.lxh.demo15.instancedemo.Person") ;  
  31.         }catch(ClassNotFoundException e){  
  32.             e.printStackTrace() ;  
  33.         }  
  34.         Person per = null ; // 声明Person对象  
  35.         Constructor<?> cons[] = null ;  
  36.         cons = c.getConstructors() ;  
  37.         try{  
  38.             // 第一个数组  
  39.             per = (Person)cons[0].newInstance("李兴华",30) ;   // 实例化对象  
  40.         }catch(Exception e){  
  41.             e.printStackTrace() ;  
  42.         }  
  43.         System.out.println(per) ;   // 内容输出,调用toString()  
  44.     }  
  45. };  

     但是,从实际角度看,如果要使用反射进行对象的实例化操作,最好在类中存在无参构造。

2、取得类所实现的全部接口

Java代码  

认识反射机制
  1. package org.lxh.demo15.classinfodemo ;  
  2. public class GetInterfaceDemo{  
  3.     public static void main(String args[]){  
  4.         Class<?> c1 = null ;      // 声明Class对象  
  5.         try{  
  6.             c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象  
  7.         }catch(ClassNotFoundException e){  
  8.             e.printStackTrace() ;  
  9.         }  
  10.         Class<?> c[] = c1.getInterfaces() ;   // 以数组形式返回实现的全部接口  
  11.         for(int i=0;i<c.length;i++){  
  12.             System.out.println("实现的接口名称:" + c[i].getName()) ;   // 输出接口名称  
  13.         }  
  14.     }      
  15. };  
  16. 结果:实现的接口名称:org.lxh.demo15.China  

3、取得父类

Java代码  

认识反射机制
  1. <strong>package org.lxh.demo15.classinfodemo ;  
  2. public class GetSuperClassDemo{  
  3.     public static void main(String args[]){  
  4.         Class<?> c1 = null ;      // 声明Class对象  
  5.         try{  
  6.             c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象  
  7.         }catch(ClassNotFoundException e){  
  8.             e.printStackTrace() ;  
  9.         }  
  10.         Class<?> c2 = c1.getSuperclass() ;    // 取得父类  
  11.         System.out.println("父类名称:" + c2.getName()) ;  
  12.     }  
  13. };          
  14. 结果:父类名称:java.lang.Object  
  15. </strong>  

4、取得类中的全部构造方法

Java代码  

认识反射机制
  1. package org.lxh.demo15.classinfodemo ;  
  2. import java.lang.reflect.Constructor ;  // 导入构造方法的包  
  3. public class GetConstructorDemo01{  
  4.     public static void main(String args[]){  
  5.         Class<?> c1 = null ;      // 声明Class对象  
  6.         try{  
  7.             c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象  
  8.         }catch(ClassNotFoundException e){  
  9.             e.printStackTrace() ;  
  10.         }  
  11.         Constructor<?> con[] = c1.getConstructors() ; // 取得一个类中的全部构造  
  12.         for(int i=0;i<con.length;i++){  
  13.             System.out.println("构造方法:" + con[i]) ;   // 输出构造,直接打印  
  14.         }     
  15. }               
  16. };     
  17. 结果:  
  18. 构造方法:public org.lxh.demo15.Person()  
  19. 构造方法:public org.lxh.demo15.Person(java.lang.String)  
  20. 构造方法:public org.lxh.demo15.Person(java.lang.String,int)  

     以上的操作确实取得了类中的构造方法,但是此时是通过对象直接打印取得的,肯定会调用Constructor类中的toString()方法。

     Constructor类中存在了以下的几个方法:

    取得修饰符:public int getModifiers()

    取得方法名称:public String getName()

    取得参数的类型:public Class<?>[] getParameterTypes()

Java代码  

认识反射机制
  1. package org.lxh.demo15.classinfodemo ;  
  2. import java.lang.reflect.Constructor ;  // 导入构造方法的包  
  3. public class GetConstructorDemo02{  
  4.     public static void main(String args[]){  
  5.         Class<?> c1 = null ;      // 声明Class对象  
  6.         try{  
  7.             c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象  
  8.         }catch(ClassNotFoundException e){  
  9.             e.printStackTrace() ;  
  10.         }  
  11.         Constructor<?> con[] = c1.getConstructors() ; // 取得一个类中的全部构造  
  12.         for(int i=0;i<con.length;i++){  
  13.             Class<?> p[] = con[i].getParameterTypes() ;       // 得到构造方法中的全部参数  
  14.             System.out.print("构造方法:" ) ;     // 输出构造,直接打印  
  15.             System.out.print(con[i].getModifiers() + " ") ; // 得到修饰符  
  16.             System.out.print(con[i].getName()) ;    // 取得构造方法的名字  
  17.             System.out.print("(") ;  
  18.             for(int j=0;j<p.length;j++){  
  19.                 System.out.print(p[j].getName() + " arg" + i) ;  
  20.                 if(j<p.length-1){  
  21.                     // 判断此是否是最后一个参数  
  22.                     System.out.print(",");  // 输出“,”  
  23.                 }  
  24.             }  
  25.             System.out.println("){}") ;  
  26.         }  
  27.     }  
  28. };