JAVA反射机制及应用例子

来源:互联网 发布:webex recorder mac 编辑:程序博客网 时间:2024/05/16 19:12

JAVA 反射机制是Java 被视为动态(或准动态)语言的一个关键性质。这个机制允许程式在运行时通过Reflection APIs 取得任何一个已知名称的class 的内部资讯,包括其modifiers(诸如public, private,static 等等)、superclass(例如Object)、interfaces(例如Cloneable),也包括fields 和methods 的所有资讯, 并在运行时调用任意一个对象的方法;生成动态代理。下面以一段代码来看一下主要的Reflection APIs,代码中有相应的注释。

 

Java代码  收藏代码
  1. import java.lang.reflect.Array;  
  2. import java.lang.reflect.Constructor;  
  3. import java.lang.reflect.Field;  
  4. import java.lang.reflect.InvocationTargetException;  
  5. import java.lang.reflect.Method;  
  6. import java.lang.reflect.Modifier;  
  7.   
  8. public class Goods  
  9. {  
  10.     private String id;  
  11.     private double price;  
  12.   
  13.     public Goods(){  
  14.         System.out.println("it is a pen");  
  15.     }  
  16.       
  17.     public Goods(String s1,String s2){  
  18.         System.out.println(s1+"*"+s2);  
  19.     }  
  20.       
  21.     public String getId()  
  22.     {  
  23.         System.out.println(id);  
  24.         return id;  
  25.     }  
  26.     public void setId(String id)  
  27.     {  
  28.         this.id = id;  
  29.     }  
  30.     public String addName(String str1,String str2){  
  31.         return str1+str2;  
  32.     }  
  33.     /** 
  34.      * @throws ClassNotFoundException  
  35.      * @throws IllegalAccessException  
  36.      * @throws InstantiationException  
  37.      * @throws NoSuchMethodException  
  38.      * @throws SecurityException  
  39.      * @throws InvocationTargetException  
  40.      * @throws IllegalArgumentException  
  41.      * @throws NoSuchFieldException  
  42.      * @功能描述   
  43.      * @输入参数   
  44.      * @反馈值     
  45.      */  
  46.     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException  
  47.     {  
  48.         // TODO Auto-generated method stub  
  49.         String str = "com.xtlh.sinye.Goods";  
  50.         Class c = Class.forName(str);  
  51.         Object obj = c.newInstance();//初始化一个Goods的对象  
  52.           
  53.         /** 
  54.          * //这里设置属性的值 调用setId()方法,类型用Class[],参数用Object[] 
  55.          */  
  56.         Method m = c.getMethod("setId",new Class[]{Class.forName("java.lang.String")});   
  57.         m.invoke(obj,new Object[]{"it's apple"});   
  58.         System.out.println("---------------------------------------------------------------------");  
  59.           
  60.         /** 
  61.          * //这里是里获取属性的值 调用getId()方法 
  62.          */  
  63.         m = c.getMethod("getId",new Class[]{});   
  64.         m.invoke(obj,new Object []{});   
  65.         System.out.println("---------------------------------------------------------------------");  
  66.           
  67.         /** 
  68.          * //获得类中声明的方法 
  69.          */  
  70.         Method me[] = c.getDeclaredMethods();   
  71.         for(int i=0;i<me.length;i++){  
  72.             System.out.println("method["+i+"]="+me[i].toString());  
  73.         }  
  74.         System.out.println("---------------------------------------------------------------------");  
  75.           
  76.         /** 
  77.          * //模拟 instanceof 操作符 
  78.          */  
  79.         boolean b1 = c.isInstance(new Integer(34));  
  80.         System.out.println("Goods is a instance of Integer ? "+b1);  
  81.         boolean b2 = c.isInstance(new Goods());//这里调用了无参的构造方法  
  82.         System.out.println("Goods is a instance of Goods ? "+b2);  
  83.         System.out.println("---------------------------------------------------------------------");  
  84.           
  85.         /** 
  86.          * //找出类的方法,类的名称,类的方法的参数,类的方法的返回类型 
  87.          */  
  88.         Method med[] = c.getDeclaredMethods();   
  89.         Method med1[] = c.getMethods();//从字面意思可以看出来,这里找到所有的方法,即可以找到继承来的方法等  
  90.         for(int i=0;i<med.length;i++){  
  91.             Method mee = med[i];  
  92.             System.out.println("method # "+i+" name="+mee.getName());  
  93.             System.out.println("declaring class ="+mee.getDeclaringClass());  
  94.             //方法的参数类型  
  95.             Class pvec[] = m.getParameterTypes();  
  96.             for(int j=0;j<pvec.length;j++){  
  97.                 System.out.println("parameter # "+j+" ="+pvec[j]);  
  98.             }  
  99.             //方法的异常  
  100.             Class evec[] = m.getExceptionTypes();     
  101.             for (int j = 0; j < evec.length; j++){  
  102.                 System.out.println("exception #" + j + " " + evec[j]);     
  103.             }     
  104.             //方法的返回类型  
  105.             System.out.println("return type = " + mee.getReturnType());   
  106.         }  
  107.         System.out.println("---------------------------------------------------------------------");  
  108.           
  109.         /** 
  110.          * //获取类的构造函数 
  111.          */  
  112.         Constructor ctorlist[] = c.getDeclaredConstructors();   
  113.         for(int i=0;i<ctorlist.length;i++){  
  114.             Constructor cons = ctorlist[i];  
  115.             System.out.println("Constructor #"+i+" name="+cons.getName());  
  116.             Class[] consParaType = cons.getParameterTypes();//获得构造函数的参数类型  
  117.             if(consParaType.length==0){  
  118.                 System.out.println("Constructor have no parameters");  
  119.             }else{  
  120.                 for(int j=0;j<consParaType.length;j++){  
  121.                     System.out.println("Constructor Parameter type #"+j+" name="+consParaType[j]);  
  122.                 }  
  123.             }  
  124.         }  
  125.         System.out.println("---------------------------------------------------------------------");  
  126.           
  127.         /** 
  128.          * //获取类的属性 
  129.          */  
  130.         Field fieldlist[] = c.getDeclaredFields();     
  131.         for(int i=0;i<fieldlist.length;i++){  
  132.             Field field = fieldlist[i];  
  133.             System.out.println("Filed #"+i+" name="+field.getName());//属性名称  
  134.             System.out.println("Filed #"+i+" type="+field.getType());//属性类型  
  135.               
  136.             int mod = field.getModifiers();   
  137.             System.out.println("modifiers = " + Modifier.toString(mod));//属性的修饰符 private/public/protected  
  138.         }  
  139.         System.out.println("---------------------------------------------------------------------");  
  140.           
  141.         /** 
  142.          * //根据方法的名称来执行方法 
  143.          */  
  144.         Class cls = Class.forName("com.xtlh.sinye.Goods");     
  145.         Class partypes[] = new Class[2];     
  146.         partypes[0] = String.class;//更多类型 Long.TYPE Integer.TYPE,或者使用Long.class、Integer.class  
  147.         partypes[1] = Class.forName("java.lang.String");     
  148.         Method meth = cls.getMethod("addName", partypes);     
  149.         Goods goods = new Goods();     
  150.         Object arglist[] = new Object[2];     
  151.         arglist[0] = new String("love");     
  152.         arglist[1] = new String("grape");     
  153.         Object retobj = meth.invoke(goods, arglist);     
  154.         String retval = (String) retobj;     
  155.         System.out.println(retval);   
  156.         System.out.println("---------------------------------------------------------------------");  
  157.           
  158.         /** 
  159.          * 创建对象,根据指定的参数类型找到相应的构造函数并执行它,以创建一个新的对象实例。使用这种方法可以在程序运行时动态地创建对象,而不是在编译的时候创建对象,这一点非常有价值 
  160.          */  
  161.         Class clss = Class.forName("com.xtlh.sinye.Goods");     
  162.         Class partypess[] = new Class[2];     
  163.         partypess[0] = String.class;     
  164.         partypess[1] = String.class;     
  165.         Constructor ct = clss.getConstructor(partypess);     
  166.         Object arglists[] = new Object[2];     
  167.         arglists[0] = new String("hello");     
  168.         arglists[1] = new String("orange");     
  169.         Object retobjs = ct.newInstance(arglists);   
  170.         System.out.println("---------------------------------------------------------------------");  
  171.           
  172.         /** 
  173.          * //改变属性的值 
  174.          */  
  175.         Class ccc = Class.forName("com.xtlh.sinye.Goods");   
  176.         Field fld = ccc.getDeclaredField("price");     
  177.         Goods goods1 = new Goods();     
  178.         System.out.println("price = " + goods1.price);     
  179.         fld.setDouble(goods1, 25.0);     
  180.         System.out.println("price = " + goods1.price);     
  181.         System.out.println("---------------------------------------------------------------------");  
  182.           
  183.         /** 
  184.          * //简单使用数组,创建了 10 个单位长度的 String 数组,为第 5 个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来 
  185.          */  
  186.         Class cla = Class.forName("java.lang.String");     
  187.         Object arr = Array.newInstance(cla, 10);     
  188.         Array.set(arr, 5, "hello Watermelon");     
  189.         String s = (String) Array.get(arr, 5);     
  190.         System.out.println(s);     
  191.         System.out.println("---------------------------------------------------------------------");  
  192.           
  193.         /** 
  194.          * //复杂数组使用,例中创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为 37。注意,多维数组实际上就是数组的数组,例如,第一个 Array.get 之后,arrobj 是一个 10 x 15 的数组。进而取得其中的一个元素,即长度为 15 的数组,并使用 Array.setInt 为它的第 10 个元素赋值。 
  195.             注意创建数组时的类型是动态的,在编译时并不知道其类型。 
  196.          */  
  197.         int dims[] = new int[]{5, 10, 15};     
  198.         Object array = Array.newInstance(Integer.TYPE, dims);     
  199.         Object arrobj = Array.get(array, 3);     
  200.         Class cl = arrobj.getClass().getComponentType();     
  201.         System.out.println(cl);     
  202.         arrobj = Array.get(arrobj, 5);     
  203.         Array.setInt(arrobj, 10, 37);     
  204.         int arrcast[][][] = (int[][][]) array;     
  205.         System.out.println(arrcast[3][5][10]);     
  206.     }  
  207.   
  208. }  

原创粉丝点击