类加载器,反射,动态代理
-
类加载器
当程序要使用某个类时,如果这个类还没有被加载到内存中,那么系统会通过加载,连接,初始化三步来实现对这个类进行初始化
(1)加载
将class文件读入内存,并为之创建一个class对象,任何类被使用时都会建立一个class对象(理解:程序经过编译之后,会从java文件生成class文件,这个时候的加载过程就是从硬盘上面加载class文件到内存,Java运行的是.class文件,基于java中万物皆对象的原则,java把.class文件作为一个类来表示,这个类就叫做class类,这个类被称呼为字节码文件)
(2)连接
-
验证:验证class文件是否有正确的内部结构,验证是否与其他类一致
-
准备
-
解析
(3)初始化:赋值
-
栈内存和堆内存都是在这个时候赋值吗
-
反射:
所有的项目的框架基本上都是用反射来封装的,学了反射,有助于理解框架
在不能new对象时,可以通过反射将这个对象new出来,并且可以访问其内部的属性和方法(包括私有的)
反射实际上操作的是class文件,java把所有的class文件都封装到了一个叫Class的类里面,这个类被称为字节码对象获取字节码文件的三种方式:
(1)object的getclass方法,就会返回这个类的字节码文件(不常用,因为这是在可以new对象的情况下使用的)【object是被new出来的对象】
(2)通过类名.class来得到其字节码文件
(3)用得较多:Class.forName(“全类名”)反射的步骤:
(1)获取该类的字节码文件对象
Class class=Class.forName(“全类名”)
(2)得到该类的构造方法
Class类的方法:
常用:得到constructor对象,可以传参(得到公共的有参构造方法,若需要传入的参数是String类型,此时参数为String.class),不传参(得到公共的无参构造方法)
然后将constructor对象调用方法【newinstance(实参)】就new成功了不常用:得到constructor数组,里面封装了这个类所有的公共构造方法
使用私有构造方法
Constructor coon=classz.getDeclaredConstructors();
// classz是字节码文件,但是还要在后面加上(只要是私有的,都要暴力访问)
Conn.setAccessible(true) // 暴力访问
(3)访问其属性
通过字节码对象获取到name属性的对象
Field field =classz.getField(“name”);
Field的方法如下:
获取该字段的值,obj传入刚刚通过newinstance创建的对象
(4)访问其方法
Method method=classz.getMethod("方法名",参数类型);
method.invoke(对象名,实参);
获取私有方法:
Method method=classz.getDeclaredMethod("方法名",参数类型);
method.setAccessible(true);//暴力访问
method.invoke(对象名,实参);
获取私有属性时同样(+declared,+暴力访问)
5. 动态代理
- [ ] 待完成