【java总结】反射

来源:互联网 发布:cbox网络电视官方 编辑:程序博客网 时间:2024/06/03 21:39

JAVA反射机制

JAVA有着一个非常突出的动态相关机制:Reflection,即反射机制,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。


public class Person{        public Person() {             }    public Person(String name){        this.name=name;    }    public Person(int age){        this.age=age;    }    public Person(String name, int age) {        this.age=age;        this.name=name;    }    public String getName() {        return name;    }    public int getAge() {        return age;    }    @Override    public String toString(){        return "["+this.name+"  "+this.age+"]";    }    public void reflect1() {        System.out.println("Java 反射机制 - 调用某个类的方法.");    }    public void reflect2(int age, String name) {        System.out.print("Java 反射机制 - 调用某个类的方法.");        System.out.println("age -> " + age + ". name -> " + name);    }    private String name;    private int age;}


public class ReflectTest {public static void main(String[] args) throws Exception{//通过Object的getClass方法获取Class对象Date date1 = new Date(); Date date2 = new Date();Class<?> class1=date1.getClass();Class<?> class2=date2.getClass();System.out.println("类全称: "+class2.getName());//类全称: java.util.DateSystem.out.println("类名: "+class2.getSimpleName());//类名: DateSystem.out.println(class1==class2);//true//使用.class的方法,并不需要有该类的对象存在Class<?> stringClass=String.class;System.out.println("类全称: "+stringClass.getName());//类全称: java.lang.StringSystem.out.println("类名: "+stringClass.getSimpleName());//类名: String//使用Class.forName()方法Class<?> numClass=Class.forName("Collection.Num");System.out.println("类全称:"+numClass.getName());//类全称:Collection.NumSystem.out.println("类名:"+numClass.getSimpleName());//类名:Num//通过Class的newInstance实例化对象(需要有无参构造方法)Date newDate=(Date)class1.newInstance();System.out.println(newDate);//Sat Feb 11 21:19:06 GMT+08:00 2017//通过Class的newInstance调用对应的构造函数实例化对象Person per1=null;        Person per2=null;        Person per3=null;        Person per4=null;        Class<?> per=Class.forName("Reflect.Person");        //获得全部构造函数        Constructor<?>[] constructor=per.getConstructors();        System.out.println("构造方法: "+constructor[0]);//构造方法: public Reflect.Person(java.lang.String,int)        System.out.println("构造方法: "+constructor[1]);//构造方法: public Reflect.Person(int)        System.out.println("构造方法: "+constructor[2]);//构造方法: public Reflect.Person(java.lang.String)        System.out.println("构造方法: "+constructor[3]);构造方法: public Reflect.Person()        per1=(Person)constructor[3].newInstance();        per2=(Person)constructor[2].newInstance("Rollen");        per3=(Person)constructor[1].newInstance(20);        per4=(Person)constructor[0].newInstance("Rollen",20);        System.out.println(per1);[null  0]        System.out.println(per2);[Rollen  0]        System.out.println(per3);[null  20]        System.out.println(per4);[Rollen  20]        //返回一个类实现的接口        Class<?> interfaces[]=stringClass.getInterfaces();        for(int i=0;i<interfaces.length;i++){        System.out.println("实现的接口   "+interfaces[i].getName());        }//实现的接口   java.io.Serializable;实现的接口   java.lang.Comparable;实现的接口   java.lang.CharSequence        //取得父类        Class<?> superClass=stringClass.getSuperclass();        System.out.println("继承的父类为:"+superClass.getName());//继承的父类为:java.lang.Object        // 取得本类的全部属性        Field[] field=stringClass.getDeclaredFields();        for(int i=0;i<field.length;i++){        //获取权限修饰符        int modify=field[i].getModifiers();        String priv = Modifier.toString(modify);        //获取属性类型        Class<?> type=field[i].getType();        System.out.println(priv+"-----"+type.getName()+"-----"+field[i].getName());        }        //取得实现的接口或者父类的属性        System.out.println("---------------------------------");        Field[] field2=stringClass.getFields();        for(int i=0;i<field2.length;i++){        //获取权限修饰符        int modify=field2[i].getModifiers();        String priv = Modifier.toString(modify);        //获取属性类型        Class<?> type=field2[i].getType();        System.out.println(priv+"-----"+type.getName()+"-----"+field2[i].getName());        }        //通过反射访问修改私有属性        System.out.println("修改前:"+per4);        Field privateField=per.getDeclaredField("name");        privateField.setAccessible(true);        privateField.set(per4, "Mankind");        System.out.println("修改后:"+per4);        //获取某个类的全部方法        Method[] method=Object.class.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.println("第"+i+"个方法:");        System.out.println("访问权限:"+Modifier.toString(temp));        System.out.println("返回类型:"+returnType.getName());        System.out.println("方法名:"+method[i].getName());        if(para.length!=0){        System.out.println("参数列表:");            for(int j=0;j<para.length;j++){            System.out.println("参数1:"+para[j].getName());            }        }        }        //调用某个类的无参/有参方法        Method method1=per.getMethod("reflect1");        method1.invoke(per.newInstance());        Method method2=per.getMethod("reflect2",int.class,String.class);        method2.invoke(per.newInstance(),1000,"老王");        //反射实例:在泛型为Integer的ArrayList中存放一个String类型的对象        ArrayList<Integer> list = new ArrayList<Integer>();        Method method3 = list.getClass().getMethod("add", Object.class);        method3.invoke(list, "Welcome to JAVA");        System.out.println(list.get(0));        //通过反射取得并修改数组的信息        int[] intArray={1,2,3,4,5};        Class<?> demo=intArray.getClass().getComponentType();        System.out.println(demo.getName());        System.out.println(Array.getLength(intArray));        System.out.println("数组的第一个元素: " + Array.get(intArray, 0));        Array.set(intArray, 0, 100);        System.out.println("修改之后数组第一个元素为: " + Array.get(intArray, 0));        }}


动态代理

对于普通的静态代理,一个代理类需要对应一个事先真实存在的对象,在实际操作中,如果大量使用静态代理必然导致类的膨胀,如果事先并不知道真实角色,该如何使用代理呢?动态代理的存在解决了这样一个问题。可以通过Java的动态代理类来解决。

动态代理的步骤
(1).创建一个实现接口InvocationHandler的类,它必须实现invoke方法
(2).创建被代理的类以及接口
(3).通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
(4).通过代理调用方法

public interface ProxyInterface {public void say();}

public class ProxyObject implements InvocationHandler{    private Object proxied = null;//这里我们并不知道要代理的对象是谁,所以用一个Object代替    public ProxyObject(){            }    public ProxyObject(Object proxied){        this.proxied  = proxied;    }    public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {        System.out.println("你好!");        return arg1.invoke(proxied, arg2);    };}

public class RealObject implements ProxyInterface{    public void say(){        System.out.println("i'm talking");    }}

public class DynamicProxyTest {static void customer(ProxyInterface pi){        pi.say();    }    public static void main(String[] args){        RealObject real = new RealObject();        ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, new ProxyObject(real));        customer(proxy);    }}



0 0