黑马程序员——09 高新技术(二)一个例子学会使用反射机制

来源:互联网 发布:淘宝食品详情页模板 编辑:程序博客网 时间:2024/06/18 17:32

  ------- android培训、java培训、期待与您交流! ----------


当我们写好一个程序时,Java 语言把每个单独的类 Class 和接口 Implements 编译成单独的一个 . class 文件,这些文件对于 Java 运行环境来说就是一个个可以动态加载的单元。此外这些class文件就是这些类或接口的字节码文件,为了操作这些字节码文件,java把这些字节码文件归为Class类。

那么怎样来理解Class类呢?

类就是一些具有相同特性的对象的抽象形式,比如Person类,就把人的姓名,年龄,身高等共有的数据给抽象出来。

而Class类就是所有类字节码文件对象的抽象形式,所有的类都是具有字段,构造方法,成员方法这些相同的元素,

Class类就把这些类共有的特性分为了Field,Constructor,Method类。

而反射就是建立在Class类的基础上来动态的获取类中的信息,调用这些类的方法和属性,要想操作这些类必须先获得这些类的字节码文件对象。比如Person类就具有自己特有的字节码文件,他的对象P1和P2所对应的类的字节码文件都是一样的。

下面通过一个例子就把关于反射的大部分操作方法给展现出来。

[java] view plaincopy
  1. //定义一个Person类,分别有公有和私有的构造方法、字段和方法,然后用反射来操作这个类  
  2. public class Person {  
  3.     private String namePrivate;  
  4.     public static int ageStatic;  
  5.     public String namePublic;  
  6.     public int agePublic;  
  7.       
  8.       
  9.      Person() {  
  10.           
  11.     }  
  12.       
  13.     public Person(String namePublic,int agePublic)  
  14.     {  
  15.         this.namePublic = namePublic;  
  16.         this.agePublic = agePublic;  
  17.         System.out.println("我是公有构造方法"+"公有字段"+namePublic+agePublic);  
  18.     }  
  19.       
  20.     public Person(int agePublic)  
  21.     {  
  22.         this.agePublic = agePublic;  
  23.     }  
  24.       
  25.     private Person(String namePrivate)  
  26.     {  
  27.         this.namePrivate = namePrivate;  
  28.         System.out.println("我是私有有构造方法"+"私有字段"+namePrivate);  
  29.     }  
  30.   
  31.     public Person getPersonPublic(String namePublic ,int agePublic )  
  32.     {  
  33.         this.agePublic = agePublic;  
  34.         this.namePublic = namePublic;  
  35.         Person p = new Person();  
  36.         return p;  
  37.     }  
  38.       
  39.     public int  getAgePublic()//空参数的构造方法  
  40.     {  
  41.         return agePublic;  
  42.     }  
  43.       
  44.     private String getNamePrivate(String name)  
  45.     {  
  46.         return namePrivate;  
  47.     }  
  48.       
  49.     public static int getAgeStatic(int age)  
  50.     {  
  51.         Person.ageStatic = age;  
  52.         return ageStatic;  
  53.     }  
  54. }  


 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import java.lang.reflect.Constructor;  
  2.   
  3.   
  4. import java.lang.reflect.Field;  
  5. import java.lang.reflect.Method;  
  6.   
  7. import javax.activation.FileDataSource;  
  8.   
  9. import cn.cn.cn.Student;  
  10.   
  11. public class ClassDemo {  
  12.   
  13.     public static void main(String[] args) throws Exception  
  14.     {  
  15.         new Student();  
  16.         /* 
  17.          * 有三种方式可以得到Person类的Class 
  18.          * 方式一:知道Person的一个对象p 
  19.          *        Class c1 = p.getClass(); 
  20.          * 方式二:知道有个类叫Person   
  21.          *        Class c2 = Person.class; 
  22.          * 方式三:知道有个类叫Person  此种方式的字符串参数要包括包名,一般是通过配置文件获得的 
  23.          *        Class c3 = Class.forName("Person"); 
  24.          */  
  25.           
  26.          //方式一:必须要先有个对象  
  27.          Person p = new Person();  
  28.          Class c1 = p.getClass();  
  29.            
  30.          //方式二  
  31.          Class c2 = Person.class;  
  32.            
  33. //       方式三  
  34.          Class c3 = Class.forName("Person");//Person保存在默认包中  
  35.          //如果我们定义一个Student类他的包名为 cn.cn.cn,用之前先导入包,最上面:import cn.cn.cn.Student;  
  36.          Class c4 = Class.forName("cn.cn.cn.Student");  
  37.          System.out.println(c4);  
  38.          /* 
  39. 1         * 构造方法的获得方式 
  40.           *  
  41.           * 1.获得公有的构造方法 
  42.           *  1.1获得所有的公有方法 
  43.           *  1.2获得指定的公有方法 
  44.           * 2.获得所有的构造方法 
  45.           *  2.1获得所有的方法 
  46.           *  2.2获得指定的私有方法 
  47.           */  
  48.            
  49.          //1.1获得所有公有的构造方法,调用Class对象的getConstructors方法,他会返回返回一个包含某些 Constructor 对象的数组  
  50.              Constructor[] cons = c1.getConstructors();  
  51.              for(Constructor s : cons)  
  52.              {  
  53.                  System.out.println(s); //打印结果public Person(int)  public Person(java.lang.String,int)  
  54.                
  55.              }  
  56.            // 1.2 获得指定的公有方法,调用Class方法的getConstructor方法,返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。  
  57.                  //指定的方法就是将构造方法的参数值传入  
  58.              Constructor con = c1.getConstructor(String.class,int.class);  
  59.              System.out.println(con);  //  public Person(java.lang.String,int)  
  60.               
  61.            // 2.获得所有的私有方法以及指定的私有方法,与上面的方法类似,就多了个Declared关键字  
  62.              Constructor[] conprs = c1.getDeclaredConstructors();  
  63.              Constructor conpr = c1.getDeclaredConstructor(String.class);  
  64.              
  65.     /***************************************************************************************/  
  66.      /* 
  67. 2      * 获得字段的方法 
  68.         2.1获得所有的公有字段 
  69.         2.2获得所有的字段 
  70.         2.3获得指定的私有字段 
  71.          
  72.       */       
  73.                
  74.         //获得所有的公有字段  
  75.              Field[] filed = c1.getFields();   
  76.         //获得所有的 私有有字段       
  77.              Field[] fieldpr = c1.getDeclaredFields();  
  78.         //获得指定的私有字段namePrivate  
  79.              Field f = c1.getDeclaredField("namePrivate");  
  80.              System.out.println(f);  
  81.    /***************************************************************************************/       
  82.  /* 
  83. 3     * 获得字段的方法 
  84.          3.1获得所有的公有方法 
  85.          3.2获得所有的方法 
  86.          3.3获得指定的公有方法 
  87.          3.4获得静态方法 
  88. */            
  89.     //3.1获得所有的公有方法  
  90.           Method []  ms = c1.getMethods();  
  91.     //3.1获得所有的方法       
  92.           Method []  mps = c1.getDeclaredMethods();  
  93.     //3.3获得指定的公有方法,调用getDeclaredMethod(String name ,Class<?>... parameterTypes)  
  94.     //  他又两个参数,name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组,  
  95.     //它按声明顺序标识该方法的形参类型。    
  96.           Method m = c1.getDeclaredMethod("getNamePrivate", String.class);  
  97.           //如果想获取空参数的构造方法,将参数表写为null就行了  
  98.            Method mnull = c1.getMethod("getAgePublic"null);  
  99.     //3.4获得静态方法,和普通的获得方法没什么不同  
  100.           Method mm = c1.getMethod("getAgeStatic"int.class);  
  101.           /***************************************************************************************/  
  102.     /* 
  103. 4       如何利用反射实例化一个对象,并使用它的方法 
  104.         4.1利用方式实例化一个对象 
  105.            4.1.1利用默认的无参构造函数实例化一个对象 
  106.            4.1.2利用指定的公共的构造函数实例化一个对象 
  107.            4.1.3利用指定的私有的构造函数实例化一个对象 
  108.             
  109.                   
  110.         4.2利用反射使用方法 
  111.            4.2.1使用公共的方法 
  112.            4.2.2使用私有的方法 
  113.            4.2.3使用静态方法 
  114.  *  */        
  115.             
  116.           // 4.1.1利用默认的无参构造函数实例化一个对象  
  117.           Person p1 = (Person)c1.newInstance();  
  118.           // 4.1.2利用指定的公共的构造函数实例化一个对象  
  119.           Constructor con1 = c1.getConstructor(String.class,int.class);  
  120.           Person p2 =  (Person)con1.newInstance("liming",20);  
  121.           System.out.println(p2.agePublic+p2.namePublic);  
  122.           //利用指定的私有的构造函数实例化一个对象  
  123.           Constructor con3 = c1.getDeclaredConstructor(String.class);  
  124.           //私有的必需要设置访问权限,否则不能访问,对于字段和方法也是一样的  
  125.            con3.setAccessible(true);  
  126.            con3.newInstance("wang");  
  127.             
  128.              
  129.            // 4.2.1使用公共的方法  
  130.            Method m1 = c1.getMethod("getAgePublic"null);  
  131.            Object obj = c1.newInstance();  
  132.              
  133.            int age = (Integer) m1.invoke(obj, null);  
  134.            //4.2.2使用私有的方法,与上面类似,只要设置权限就可以了  
  135.            //4.2.3使用静态方法。和上面类似,只要invoke的第一个参数设为null  
  136.            Method m2 = c1.getMethod("getAgeStatic"int.class);  
  137.            int age1 = (Integer) m2.invoke(null24);  
  138.            System.out.println(age1);  
  139.              
  140.              
  141.     }  
  142. }  


 


  ------- android培训、java培训、期待与您交流! ----------

0 0