介绍
本章主要讲解反射与动态代理回顾范型知识,为了强化反射与动态代理,经过本人认真研究后总结写下此文章。
什么是反射
在我们开发过程中不知道我要初始化对象是什么类,无法new创建对象,这个时候就需要使用反射进行初始化对象并获取里面的方法。适用于各种框架。是java实现动态语言的方式,无限私有方法调用。反射效率慢。
##从静态代理到动态代理
类加载器
反射的步骤
1.获取目标对象的class,一般使用Class.forName(String clazzName);
2.通过class对象分别获得该类型的,构造函数,属性,方法。
3.通过获得的属性和方法,进行进一步操作。
反射类
反射的完成依赖了Java提供的反射类,Class,Constructor(构造器),Field(属性), Method(方法)。
Java获取Class的三种方式
1.使用Class的forName(String clazzName)方法,传入字符串,传入为类的全限定名。
2.调用某个类的class属性,
3.调用getClass方法获得。
大部分情况下我们都是通过第二,三种方式获得class对象,在反射中,我们都用的是第一种方法,该方法会
报出ClassNotFoundException异常。
//通过getClass()方法获得
Boolean tian = true;
Class<?> clazz = tian.getClass();
System.out.println(clazz); //输出结果为:java.lang.Boolean
//通过class方法获得。
Class<?> clazz = Boolean.class;
System.out.println(clazz); //输出结果为:java.lang.Boolean
//通过Class.forName(String clazzName)获得
Class<?> clazz = Class.forName(“java.lang.Boolean”);
System.out.println(clazz); //输出结果为:java.lang.Boolean
//class类的其他用法
getSupperClass();//获取父类class
String getName(); //获取类的完整类名
//快速创建一个类的实例。调用默认构造器,若没有则报异常
Object newInstance();
通过class对象获得Constructor,Field,Method对象
/**
- Constructor(类构造器的获取)
- 带“declared”的方法可以获取包括继承,public不包括private的构造函数
- 不带的无法获取继承,可以获取public,protected,private和默认包访问的构造函数。
*/
//获取所有的构造函数(公共/继承)
Constructor<?>[] getConstructors();
//指定参数获取类的特定构造函数(传入构造函数的参数类型)
Constructor getConstructors(Class<?>… parameterTypes)
//获取指定的构造函数不包括继承
Constructor getDeclaredConstructor(Class<?>… parameterTypes);
//获取所有的构造函数不包括继承的
Constructor<?> getDeclaredConstructor();
/**
- 获取类属性
*/
//获取指定属性,传入属性名(公共和继承)
Field getField(String name);
//获取所有属性(公共和继承)
Field[] getFields();
//获取指定的属性(不包括继承)
Field getDeclaredField(String name);
//获取所有属性(不包括继承)
Field[] getDeclaredFields();
/**
-
获取类的方法
/
//获取指定的方法(公共/继承),传入方法名,方法参数
Method getMethod(String name, Class<?>… parameterTypes);
//获取所有的指定方法(公共、继承)
Method getMethods();
//获取指定的方法(不包括继承)
Method getDeclaredMethod(String name, Class<?>… parameterTypes);
//获取所有的方法(不包括继承)
Method[] getDeclaredMethods();
通过获取的各个类信息进行进一步操作。
/* -
通过Constructor类对象获取构造函数信息
/
String getName();//获取构造器名
Class getDeclaringClass();//获取一个用于描述类中定义的构造函数的class对象。
int getModifiers(); //返回int, 获取构造函数的修饰符等级。
Class[] getExceptionTypes();//获取描述方法抛出的异常类型的Class对象数组。
Class[] getParameterTypes();//获取描述参数类型的Class对象数组。
constructor.newInstance(Class<?>… parameterTypes);//通过获取的构造函数类,通过指定
参数类调用该来的指定构造函数,创建该类型的实例对象。
/* -
通过Field类对象获取构造函数信息
/
String getName(); //获取属性名
Class getDeclaringClass(); //获取Class对象,一般为声明该属性的类的类型class
Class getType(); //获取属性类型的Class对象。
int getModifiers(); //返回int, 获取构造函数的修饰符等级。
Object get(Object obj);//返回该类型的对象上该属性的值。
void set(Object obj,Object Value);//为该类型Class的对象的指定对象,的指定属性赋值。
/* -
通过Method类对象获取构造函数信息
*/
String getName();//获取方法名
Class getDeclaringClass(); //获取Class对象,一般为声明该方法的类的类型class
int getModifiers(); //返回int, 获取构造函数的修饰符等级。
Class[] getExceptionTypes();//获取描述方法抛出的异常类型的Class对象数组。
Class[] getParameterTypes();//获取描述参数类型的Class对象数组。
Object invoke(Object obj,Class<?>… parameterTypes);//通过反射结合类的实例对象调用函数。
注意
Java反射默认受限于Java的访问控制。如:无法访问private私有的方法和字段,Java的安全机制不允许查看
这些对象的直接值,若强制读取则抛出异常从动态代理到静态代理
代理模式
代理模式是给目标对象提供一个代理对象由代理对象控制对目标对象对引用。比如你叫跑腿或外卖,骑手就是代理帮你去店里买东西,骑手再给你你想买对东西。这样是不是省去你和店家直接对交互。
静态代理
针对单个代理目标对象进行调用,违反了6大原则中的开闭原则,因此引出了动态代理。
动态代理
需要使用反射进行动态的满足所有购物着需求,这样就完全避免了 静态代理的开闭原则劣势,扩展性更强。
##从源码了解
##retrofit 是如何使用的
create 方法使用动态代理调用解析类调用。