反射和动态代理

详解

反射与动态代理
  • 获取class的方式
    package reflection;
    //关于反射
    import java.lang.reflect.*;
    import java.lang.reflect.Constructor;
    import java.util.*;
    ​
    public class Test {
        //reflect包下核心接口和类
        /**
         * Member 接口 - 反映关于单个成员(字段或方法)或构造函数的标识信息。
         * Field 类 - 提供一个类的域的信息以及访问类的域的接口。
         * Method 类 - 提供一个类的方法的信息以及访问类的方法的接口。
         * Constructor 类 - 提供一个类的构造函数的信息以及访问类的构造函数的接口。
         * Array 类 - 该类提供动态地生成和访问 JAVA 数组的方法。
         * Modifier 类 - 提供了 static 方法和常量,对类和成员访问修饰符进行解码。
         * Proxy 类 - 提供动态地生成代理类和类实例的静态方法。
         */
    ​
        //获取class的三种方式
        //1.Class.forName(),使用类的全限定名
        public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    //        try {
    //            Class c1= Class.forName("[D");
    //            System.out.println(c1.getName()); //虚拟机中的class的表示
    //            System.out.println(c1.getCanonicalName());//更具体的表示,对于array和内部类来说
    //            Class c2 =Class.forName("[Ljava.lang.String;");
    //            System.out.println(c2.getCanonicalName());
    //        } catch (ClassNotFoundException e) {
    //            e.printStackTrace();
    //        }
            testClass();
            System.out.println("");
            testGetClass();
            System.out.println("");
            testInstanceOf();
            System.out.println("");
            testNewInstance();
        }
        //.class()
        public static void testClass(){
            Class c1 =int.class;
            System.out.println(c1.getCanonicalName());
            Class c2=Test.class;
            System.out.println(c2.getCanonicalName());
        }
        //使用Object.getClass
        public static void testGetClass(){
            Class c1="zhouy".getClass();
            System.out.println(c1.getCanonicalName());
            Set<String> set =new HashSet<>();
            Class c2 =set.getClass();
            System.out.println(c2.getCanonicalName());
        }
        //判断某个对象是否位某个类的实例
        public static void testInstanceOf(){
            ArrayList arrayList =new ArrayList();
            System.out.println(arrayList instanceof List);
        }
        //创建实例
    ​
        /**
         * 1.用Class对象的newInstance
         * 2.用Constructor对象的newInstance
         */
        public static void testNewInstance() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            //1.
            Class<StringBuffer> c1 = StringBuffer.class;
            StringBuffer stringBuffer = c1.newInstance();
            System.out.println(stringBuffer.append("aaa"));
            //2.
            Class<String> c2 = String.class;
            Constructor<String> constructor = c2.getConstructor(c2);
            String s = constructor.newInstance("bbb");
            System.out.println(s);
        }
    }
    //output:
    int
    reflection.Test
    ​
    java.lang.String
    java.util.HashSet
    ​
    true
    ​
    aaa
    bbb
  • 获取Field
    package reflection;
    ​
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    ​
    class Test2{
        public boolean[][] b = {{false, false}, {true, true}};
        public String name="zhouy";
        public List<Integer> list= new ArrayList<>(Arrays.asList(1,2,3));
        private String lover="???";
    }
    ​
    /**
     * getFiled - 根据名称获取公有的(public)类成员。
     * getDeclaredField - 根据名称获取已声明的类成员。但不能得到其父类的类成员。
     * getFields - 获取所有公有的(public)类成员。
     * getDeclaredFields - 获取所有已声明的类成员。
     */
    public class FieldDemo {
        public static void main(String[] args) throws NoSuchFieldException {
    //        Field b = Test2.class.getField("b");
    //        System.out.println(b);
    //        System.out.println(b.getType());
    //
    //        Field name = Test2.class.getField("name");
    //        System.out.println(name.getType());
    ​
    //        Field[] fields = Test2.class.getFields();
    //        for (Field field : fields) {
    //            System.out.println(field.getType());
    //        }
            //无法获取private,只能获取public
    //        System.out.println(Test2.class.getField("lover").getType());
            //可以获取全部
            System.out.println(Test2.class.getDeclaredField("lover").getType());
        }
    }
    //output:
    class java.lang.String
  • 获取method和上面基本一样
    package reflection;
    ​
    /**
     * getMethod - 返回类或接口的特定方法。其中第一个参数为方法名称,后面的参数为方法参数对应 Class 的对象。
     * getDeclaredMethod - 返回类或接口的特定声明方法。其中第一个参数为方法名称,后面的参数为方法参数对应 Class 的对象。
     * getMethods - 返回类或接口的所有 public 方法,包括其父类的 public 方法。
     * getDeclaredMethods - 返回类或接口声明的所有方法,包括 public、protected、默认(包)访问和 private 方法,但不包括继承的方法。
     */
    public class MethodDemo {
    }
  • 获取构造函数
    package reflection;
    ​
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    ​
    /**
     * getConstructor - 返回类的特定 public 构造方法。参数为方法参数对应 Class 的对象。
     * getDeclaredConstructor - 返回类的特定构造方法。参数为方法参数对应 Class 的对象。
     * getConstructors - 返回类的所有 public 构造方法。
     * getDeclaredConstructors - 返回类的所有构造方法。
     *
     */
    public class ConstructorDemo{
        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
            //获取所有构造方法
    //        Constructor<?>[] declaredConstructors = String.class.getDeclaredConstructors();
    //        for (Constructor declaredConstructor : declaredConstructors) {
    //            System.out.println(declaredConstructor);
    //        }
    ​
            Constructor<String> constructor = String.class.getConstructor(String.class);
            System.out.println(constructor);
            String s = constructor.newInstance("I love java");
            System.out.println(s);
        }
    }
    //output:
    public java.lang.String(java.lang.String)
    I love java
  • 静态代理
    package reflection;
    ​
    /**
     * 静态代理模式(时间模式中)
     */
    interface Marry{
        void doMarry();
    }
    class You implements Marry{
        @Override
        public void doMarry() {
            System.out.println("我要结婚了");
        }
    }
    ​
    class WeddingCompany implements Marry{ //作为代理中介
        private You you;
    ​
        public WeddingCompany(You you){
            this.you =you;
        }
        @Override
        public void doMarry() {
            if(you!=null){
                System.out.println("你要化妆");
                System.out.println("你要去接亲");
                you.doMarry();
                System.out.println("你结账");
            }
        }
    }
    //如上就是静态代理
    public class ProxyTest {
        public static void main(String[] args) {
            You you =new You();
            Marry yourMarry =new WeddingCompany(you);
            yourMarry.doMarry();
        }
    }
  • 动态代理
    package reflection;
    ​
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    ​
    /**
     * 1.在运行状态中,需要时Subject和RealSubject中动态的创建一个Proxy,用完即销毁
     * 使用InvocationHandler接口负责所有Proxy类方法的调用,Proxy类需实现该接口
     */
    interface Subject{
        void hello(String str);
        String bye();
    }
    class RealSubject implements Subject{
    ​
        @Override
        public void hello(String str) {
            System.out.println("Hello"+str);
        }
    ​
        @Override
        public String bye() {
            System.out.println("Goodbye");
            return "over";
        }
    }
    //创建动态代理类
    class ProxyDemo implements InvocationHandler{
        //要代理的对象
        private Subject subject;
    ​
        public ProxyDemo(Subject subject){
            this.subject=subject;
        }
    ​
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Before method");
            System.out.println("Call method:" + method);
            // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler(InvocatioinHandler的实例)对象的invoke方法来进行调用
            Object invoke = method.invoke(subject, args);
            System.out.println("After method");
    ​
            return invoke;
        }
    ​
    }
    public class DynamicProxyTest {
        public static void main(String[] args) {
            Subject subject =new RealSubject(); //要代理的真实对象subject
            // 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
            InvocationHandler handler =new ProxyDemo(subject);//初始化处理器
            /*
             * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
             * 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
             * 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
             * 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
             */
            Subject proxySubject =(Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
            System.out.println(proxySubject.getClass().getCanonicalName());
            proxySubject.hello("zhouy");
            String bye = proxySubject.bye();
            System.out.println("last:"+bye);
        }
    }
    //output
    reflection.$Proxy0
    Before method
    Call method:public abstract void reflection.Subject.hello(java.lang.String)
    Hellozhouy
    After method
    Before method
    Call method:public abstract java.lang.String reflection.Subject.bye()
    Goodbye
    After method
    last:over
posted @ 2022-09-19 18:23  zhouylove  阅读(31)  评论(0)    收藏  举报