1.反射:JVM在加载类的时候,引导类加载器,来校验java代码的语法,如果语法存在问题,编译报错,没有问题则执行代码.
2.反射机制:将类的组成部分封装为其他对象.
3.反射的宗旨:
(1)获取类/接口的字节码文件对象
(2)获取构造器对象Constructor,创建类对象
(3)获取成员变量所在的对象Field,给成员变量赋值
(4)获取成员方法所在的对象Method,调用成员方法并去使用它
4.Java代码的三个阶段
(1)SORUCE:源码阶段
(2)CLASS:编译阶段/类的加载阶段
(3)RUNTIME:运行阶段
5.字节码文件对象的获取
(1)Object类的getClass()方法获取
publlic final Class> getClass
(2)任意java类型的class类型
Class 字节码文件对象名 = 类名.class
(3)反射中字节码文件对象Class里面的静态方法
public static Class> forName(String className) throws ClassFoundException //参数为类的全限定名称 //类的全限定名称:包名.类名
6.创建类的实例
方法1:
(1)获取当前类的字节码文件对象
(2).获取构造器对象Constructor:
//(1)通过Class类获取这个类所有的公共的构造方法 public Constructor>[] getConstructor() //(2)获取这个类中所有的构造方法,包括私有,受保护的.. public Constructor>[] getDeclarConstructpr() //(3)获取单个的公共的构造方法所在的Constructor public ConstructorgetConstructor(Class>... parameterTypes) //参数:参数类型的class,即类型的字节码文件对象,是可变参数,可能有参数类型;如String.class //(4)获取单个指定的构造方法 public Constructor getDeclardConstructor(Class>... parameterTypes) //参数:参数类型的字节码文件
(3).取消java语言访问检查:当构造方法不是公共方法时,需要取消java语言访问检查才能访问
public void setAccessible(boolean flag)//参数为true时取消语言检查访问
(4).通过Constructor创建当前类实例
public T newInstance(Object... initargs) //参数:实际参数,值
方法2:
Class 字节码文件对象名 = 类名.class;//获取挡墙字节码文件对象 Object object = 字节码文件对象.newInstance();//创建当前类的实例,默认执行这个类的公共的无参构造方法
7.给成员变量赋值
(1)创建当前类的实例
(2)获取成员变量所造的Field类对象
//(1)获取所有的公共的成员变量的类对象 public Field[] getFields() //(2)获取所有的成员变量,包括默认,私有的,受保护的 public Field[] getDeclaredFields() //(3)获取指定的默认的成员变量所在的字段类对象Field public Field getDeclaredField(String name)//参数为指定的成员变量名称
(3)取消私有成员变量的java语言访问检查
public void setAccessible(boolean flag)//参数为true时取消语言检查访问
(4)将参数值绑定在当前类的实例
public void set(Object object , Object value) //参数1:当前类的实例;参数2:值
8.调用成员方法并使用
(1)创建当前类的实例
(2)获取成员方法的类对象Method
//(1)获取当前类的公共的成员方法,以及包括继承类的公共方法 public Method[] getMethods() //(2)获取当前类的所有成员方法,只包含自己的不包括继承的 public Method[] getDeclaredMethods() //(3)获取当前类指定的公共的成员方法所在的Method public Method getMethod(String name, Class>... parameterTypes) //参数1:成员方法的方法名 //参数2:成员方法携带参数类型的class //(4)获取指定的私有的成员方法所在类对象Method public Method getDeclaredMethod(String name , Class>... parameterTyoes) //参数1:成员方法的方法名 //参数2:成员方法携带参数类型的class
(3)取消私有方法的java语言检查
public void setAccessible(boolean flag)//参数为true时取消语言检查访问
(4)调用
public Object invoke(Object object,Object... args) //参数1:当前类的实例 //参数2:用于方法调用的参数
9.代码修改的优化方案步骤:
(1)读取配置文件,获取资源文件所在的输入流对象
当前类的字节码文件对象.类加载器.getResourceAsStream("配置文件")
(2)创建属性集合类列表对象Properties
public Properties()
(3)加载流对象
public void load(Reader reader//参数:输入字符流
(4)通过键值对获取当前类的字节码文件对象以及当前类里的方法名
public Object setProperty(String key,String value)
(5)通过反射获取当前字节码文件对象
(6)通过反射获取成员方法的类对象Method
(7)调用方法
10.jdk动态代理
(1)动态代理:使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象
(2)作用:在不改变原来目标方法功能的前提下,在代理中增强自己的功能代码
(3)jdk动态代理的实现:利用反射实现
InvocationHandler接口:由代理实例的调用处理程序的接口,每给代理实例都有一个关联的调用处理程序,的那个代理实例上调用方法时,就要实现该接口调用invoke()方法
Object invoke(Object proxy,Method method,Object[] args) //参数1:jdk创建的代理对象 //参数2:jdk提供的Method对象,是目标类的方法 //参数3:目标方法的参数,也是有jdk提供
Method类:表示目标类中的方法
public Object invoke(Object obj,Object... args)//执行某个目标类中的方法 //参数1:从底层方法被调用的对象 //参数2:用于方法调用的参数
Proxy类:创建代理对象
public static Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h) //参数1:类加载器 //参数2:代理类(目标类)实现的接口列表 //参数3:代理类需要完成的功能 //返回值:代理对象
jdk动态代理实现的步骤:
(1)创建接口,定义代理类要完成的功能
(2)创建代理类的实现接口
(3)创建InvocationHandler接口的实现类,并在invoke()方法中完成代理类的功能
(4)使用Proxy类的静态方法创建代理对象,并把返回值转换为接口类型.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)