Java系列7 反射

2019-03-15  本文已影响0人  莫小归

参考:
反射例程:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
反射:https://www.jianshu.com/p/f67182a482eb
https://www.jianshu.com/p/779b3e27b26d
反射和动态代理:https://www.jianshu.com/p/27b255a6f479
https://www.cnblogs.com/hanganglin/p/4485999.html

一.概述

1.反射定义
2.反射的优点和缺点
3.反射的应用场景

二.反射的使用

1.Class类和类类型(class type)
2.通过反射查看类信息
//第一种方式 通过Class类的静态方法——forName()来实现
Class<?> class1 = Class.forName("com.dengxin.reflection.Demo");
//第二种方式 通过类的class属性
Class<?> class1 = Demo.class;
//第三种方式 通过对象getClass方法
Demo demo = new Demo();
Class<?> class1 = demo.getClass();
Field[] allFields = class1.getDeclaredFields();      //获取class对象的所有属性
Field[] publicFields = class1.getFields();                //获取class对象的public属性
Field ageField = class1.getDeclaredField("age");          //获取class指定属性
Field desField = class1.getField("des");                  //获取class指定的public属性
//获取class对象的所有声明方法
Method[] methods = class1.getDeclaredMethods();
//获取class对象的所有public方法 包括父类的方法
Method[] allMethods = class1.getMethods();
//返回次Class对象对应类的、带指定形参列表的public方法
Method method = class1.getMethod("info", String.class);
//返回次Class对象对应类的、带指定形参列表的方法
Method declaredMethod = class1.getDeclaredMethod("info", String.class);
//获取class对象的所有声明构造函数
Constructor<?>[] allConstructors = class1.getDeclaredConstructors();
//获取class对象public构造函数
Constructor<?>[] publicConstructors = class1.getConstructors();
//获取指定声明构造函数
Constructor<?> constructor = class1.getDeclaredConstructor(String.class);
//获取指定声明的public构造函数
Constructor publicConstructor = class1.getConstructor(String.class);
oolean isPrimitive = class1.isPrimitive();                      //判断是否是基础类型
boolean isArray = class1.isArray();                              //判断是否是数组
boolean isAnnotation = class1.isAnnotation();             //判断是否是注解类
boolean isInterface = class1.isInterface();                   //判断是否是接口类
boolean isEnum = class1.isEnum();                            //判断是否是枚举类
boolean isAnonymousClass = class1.isAnonymousClass();          //判断是否是匿名内部类
boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);        //判断是否被某个注解类修饰
String className = class1.getName();                      //获取class名字 包含包名路径
Package aPackage = class1.getPackage();               //获取class的包信息
String simpleName = class1.getSimpleName();         //获取class类名
int modifiers = class1.getModifiers();                          //获取class访问权限
Class<?>[] declaredClasses = class1.getDeclaredClasses();                  //内部类
Class<?> declaringClass = class1.getDeclaringClass();                          //外部类
Annotation[] annotations = (Annotation[]) class1.getAnnotations();    //获取class对象的所有注解
Annotation annotation = (Annotation) class1.getAnnotation(Deprecated.class);    //获取class对象指定注解
Type genericSuperclass = class1.getGenericSuperclass();               //获取class对象的直接超类的 Type
Type[] interfaceTypes = class1.getGenericInterfaces();                //获取class对象的所有接口的type集合
3.通过反射生成并操作对象
//第一种方式 Class对象调用newInstance()方法生成
Object obj = class1.newInstance();
//第二种方式 对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成
Constructor<?> constructor = class1.getDeclaredConstructor(String.class);
obj = constructor.newInstance("hello");
// 生成新的对象:用newInstance()方法
 Object obj = class1.newInstance();
//首先需要获得与该方法对应的Method对象
Method method = class1.getDeclaredMethod("setAge", int.class);
//调用指定的函数并传递参数
method.invoke(obj, 28);

三.反射与动态代理

1.代理概述
代理模式中的角色
public class ProxyDemo {
    public static void main(String args[]){
        RealSubject subject = new RealSubject();
        Proxy p = new Proxy(subject);
        p.request();
    }
}

//主题接口
interface Subject{
    void request();
}

//目标对象
class RealSubject implements Subject{
    public void request(){
        System.out.println("request");
    }
}

//代理对象
class Proxy implements Subject{
    private Subject subject;
    public Proxy(Subject subject){
        this.subject = subject;
    }
    public void request(){
        System.out.println("PreProcess");
        subject.request();
        System.out.println("PostProcess");
    }
}
2.动态代理
        //方法1:通过动态代理类的构造方法创造
        //创建一个InvocationHandler对象
        InvocationHandler handler = new MyInvocationHandler(.args..);
        //使用Proxy生成一个动态代理类
        Class proxyClass = Proxy.getProxyClass(RealSubject.class.getClassLoader(),RealSubject.class.getInterfaces(), handler);
        //获取proxyClass类中一个带InvocationHandler参数的构造器
        Constructor constructor = proxyClass.getConstructor(InvocationHandler.class);
        //调用constructor的newInstance方法来创建动态代理实例
        RealSubject real = (RealSubject)constructor.newInstance(handler);
        //方法2:通过Proxy类的newProxyInstance()静态方法直接创造
        //创建一个InvocationHandler对象
        InvocationHandler handler = new MyInvocationHandler(.args..);
        //使用Proxy直接生成一个动态代理对象
        RealSubject real =Proxy.newProxyInstance(RealSubject.class.getClassLoader(),RealSubject.class.getInterfaces(), handler);
public class DynamicProxyDemo {
    public static void main(String[] args) {
        //1.创建目标对象
        RealSubject realSubject = new RealSubject();    
        //2.创建调用处理器对象
        ProxyHandler handler = new ProxyHandler(realSubject);    
       //3.动态生成代理对象
        Subject proxySubject = (Subject)Proxy.newProxyInstance(
                RealSubject.class.getClassLoader(),RealSubject.class.getInterfaces(), handler);   
        //4.通过代理对象调用方法   
        proxySubject.request();    
    }
}

/**
 * 主题接口
 */
interface Subject{
    void request();
}

/**
 * 目标对象类
 */
class RealSubject implements Subject{
    public void request(){
        System.out.println("====RealSubject Request====");
    }
}
/**
 * 代理类的调用处理器
 */
class ProxyHandler implements InvocationHandler{
    private Subject subject;
    public ProxyHandler(Subject subject){
        this.subject = subject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //定义预处理的工作,当然你也可以根据 method 的不同进行不同的预处理工作
        System.out.println("====before====");
       //调用RealSubject中的方法
        Object result = method.invoke(subject, args);
        System.out.println("====after====");
        return result;
    }
}

月度银墙,不辨花丛哪瓣香

上一篇 下一篇

猜你喜欢

热点阅读