首页 > 编程 > Java > 正文

Java 反射机制- reflect

2019-11-08 02:06:35
字体:
来源:转载
供稿:网友
1、反射机制是什么    反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。反射其实就是实例化得到对象2、反射机制能做什么

反射机制主要提供了以下功能

在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;

生成动态代理。

下面是源码

package Test;import java.io.File;import java.io.Serializable;import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.PRoxy;import java.util.ArrayList;import org.junit.Test;import com.zking.entity.Person;public class Testreflect implements Serializable {/***  reflect  反射       2017/2/18* @throws Exception*/   private String pname = null;       @Test            public void reflect() throws Exception{        //1、通过一个对象获得完整的包名和类名        /*Testreflect  testreflect=new Testreflect();         System.out.println("Testreflect权限定名:"+testreflect.getClass().getName());*/        //Testreflect权限定名:Test.Testreflect                                //2、实例化Class类对象        /*Class<?> class1=null;        Class<?> class2=null;        Class<?> class3=null;*/        // 一般采用这种形式        /*class1=Class.forName("Test.Testreflect");        class2=new Testreflect().getClass();        class3=Testreflect.class;        System.out.println("类名称:"+class1.getName());        System.out.println("类名称:"+class2.getName());        System.out.println("类名称:"+class3.getName());*/                           //3、获取一个对象的父类与实现的接口        /*String  path="Test.Testreflect";        Class<?> class1=Class.forName(path);*/           //取得父类        /*Class<?> class2=class1.getSuperclass();        System.out.println("class1的父类:"+class2.getName());*/                   //获取所有接口        /*Class<?> ints[] =class1.getInterfaces();        for (int i = 0; i < ints.length; i++) {System.out.println((i+1)+" :"+ints[i].getName());}*/                                //4、获取某个类中的全部构造函数      通过反射机制实例化一个类的对象        Class<?> class1=Class.forName("com.zking.entity.Person");             // 第一种方法,实例化默认构造方法,调用set赋值        /**Person   person=(Person) class1.newInstance();        person.setPid(1);        person.setPname("桔梗");        person.setPsex("女");        System.out.println(person.toString());*/                     // 第二种方法 取得全部的构造函数 使用构造函数赋值        /**Constructor<?> cons[]=class1.getConstructors();*/            // 查看每个构造方法需要的参数          /**for (int i = 0; i < cons.length; i++) {        Class<?> class2[] =cons[i].getParameterTypes();                     System.out.print("cons[" + i + "] (");                         for (int j = 0; j < class2.length; j++) {if(j==class2.length-1){System.out.print(class2[j].getName());}else{System.out.print(class2[j].getName()+",");}}                         System.out.println(")");}        person=(Person) cons[1].newInstance("name","男");        System.out.println(person);        person=(Person) cons[0].newInstance(1,"names","女");        System.out.println(person);*/                                   //5、获取某个类的全部属性        /** System.out.println("=============本类属性=============");              //获取本类的全部属性        Field [] field=class1.getDeclaredFields();        for (int i = 0; i < field.length; i++) {          // 权限修饰符        int  mm=field[i].getModifiers();        String  pp=Modifier.toString(mm);          // 属性类型                        Class<?> t=field[i].getType();                        System.out.println(pp+"  "+t.getName()+"  "+field[i].getName());}*/        /**System.out.println("==========实现的接口或者父类的属性==========");             // 取得实现的接口或者父类的属性          Field [] field2=class1.getFields();          for (int j = 0; j < field2.length; j++) {        //权限修饰符     int  hh=field2[j].getModifiers(); String kk=Modifier.toString(hh);Class<?> f=field2[j].getType();System.out.println(kk+"  "+f.getName()+"  "+field2[j].getName());}*/                                    // 6、获取某个类的全部方法    /** Method[] method=class1.getMethods();         for (int i = 0; i < method.length; i++) {        Class<?> returnType=method[i].getReturnType();        Class<?>  para[] =method[i].getParameterTypes();        int temp =method[i].getModifiers();        System.out.print(Modifier.toString(temp)+"  ");        System.out.print(returnType.getName()+" ");        System.out.print(method[i].getName()+"  ");        System.out.print("(");        for (int k = 0; k < para.length; k++) {         System.out.print(para[k].getName() + " " + "arg" + k);                 if (k < para.length - 1) {                     System.out.print(",");                 }}        Class<?> exce[] =method[i].getExceptionTypes();        if (exce.length>0) {System.out.print(") throws");for (int j = 0; j < exce.length; j++) {System.out.println(exce[j].getName()+" "); if(j<exce.length-1){ System.out.println(","); }}}else{System.out.println(")");}        System.out.println(); }*/                              //7、通过反射机制调用某个类的方法       // class1.getMethod("sada");          // 1》调用TestReflect类中的reflect1方法       /**Method  method2=class1.getMethod("getPsex");          Object     object = method2.invoke(class1.newInstance());          System.out.println(object);              //调用TestReflect的reflect2方法       method2 = class1.getMethod("setPsex",String.class);       Object object2= method2.invoke(class1.newInstance(),"张三");       System.out.println(object2);*/                               //8、通过反射机制操作某个类的属性         /** Object object=class1.newInstance();          // 可以直接对 private的属性赋值          Field   field=class1.getDeclaredField("pname");          field.setaccessible(true);          field.set(object, "Java反射机制");          System.out.println(field.get(object));*/                              //9、反射机制的动态代理       /**Testreflect   testreflect=new Testreflect();       System.out.println(testreflect.getClass().getClassLoader().getClass().getName());              MyInvocationHandler  demo=new MyInvocationHandler();       Subject sub=(Subject) demo.bind(new RealSubject());       String info=sub.say("爱你", 520);       System.out.println(info);*/                                              //======== 4反射机制的应用实例  ========          // 4.1 在泛型为Integer的ArrayList中存放一个String类型的对象。         /** ArrayList<Integer> list=new ArrayList<>();          Method method=list.getClass().getMethod("add",Object.class);          method.invoke(list, "Java反射机制实例。");          int n= method.getModifiers();          System.out.println(n);          System.out.println(list.get(0));*/                 // 4.2通过反射取得并修改数组的信息       /*int [] temp={1,2,45,36,48};       Class<?> demo=temp.getClass().getComponentType();       System.out.println("数组类型:"+demo.getName());       System.out.println("数组长度:"+Array.getLength(temp));       System.out.println("数组的第一个元素: " + Array.get(temp, 0));       Array.set(temp, 0, 100000);       System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0));                                  Object obj=  Array.newInstance(demo, temp.length);      int i =Array.getLength(temp);      System.arraycopy(obj, 0, obj, 0, i);*/                       //4.3通过反射机制修改数组的大小        /*int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };           int[] newTemp = (int[]) arrayInc(temp, temp.length);           print(newTemp);           String[] atr = { "a", "b", "c" };           String[] str1 = (String[]) arrayInc(atr, atr.length);           print(str1);  */               //4.5将反射机制应用于工厂模式        /**        * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。        * Java 工厂模式可以参考        * http://baike.xsoftlab.net/view/java-factory-pattern        *         * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。        *         * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。        *         * java 读取 properties 配置文件 的方法可以参考        * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file        *         * @author xsoftlab.net        */        fruit f=Factory.getInstance("Test.Apple");        if(f!=null){        f.eat();        }       }           // 修改数组大小        public static Object arrayInc(Object obj, int len) {           Class<?> arr = obj.getClass().getComponentType();           Object newArr = Array.newInstance(arr, len);           int co = Array.getLength(obj);           System.arraycopy(obj, 0, newArr, 0, co);           return newArr;       }            // 打印     public static void print(Object obj) {         Class<?> c = obj.getClass();         if (!c.isArray()) {             return;         }         System.out.println("数组长度为: " + Array.getLength(obj));         for (int i = 0; i < Array.getLength(obj); i++) {             System.out.print(Array.get(obj, i) + " ");         }         System.out.println();     }                                                                                                                     //定义项目接口       interface Subject {           public String say(String name, int age);       }            //定义真实项目     class  RealSubject    implements  Subject{@Overridepublic String say(String name, int age) {return name+"  "+age;}          }               /**      * 在java中有三种类类加载器。      *       * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。      *       * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类      *       * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。      *       * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。      *       * @author xsoftlab.net      *       */     class  MyInvocationHandler implements InvocationHandler {                private  Object  obj=null;                public  Object  bind(Object obj){                this.obj=obj;                return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);                }@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stubObject  temp=method.invoke(this.obj, args);return temp;}          }                              interface fruit {       public abstract void eat();    }    class Apple implements fruit {       public void eat() {           System.out.println("Apple");       }    }    class Orange implements fruit {       public void eat() {           System.out.println("Orange");       }    }    static class Factory {       public static fruit getInstance(String ClassName) {           fruit f = null;           try {               f = (fruit) Class.forName(ClassName).newInstance();           } catch (Exception e) {               e.printStackTrace();           }           return f;       }    }}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表