ClassLoader类加载实例和反射加载实例的区别
ClassLoader类加载实例和反射加载实例不能论区别,因为两者不是对立关系,而是统一关系。类加载的作用是将class文件字节码内容加载到内存中,在堆内存的方法区中就会产生一个Class类型的对象,这个对象就像一面镜子可以反射到类的结构,我们称之为反射加载。
1.ClassLoader类加载
ClassLoader中的类加载过程其实是一个很复杂的过程,主要包括下面的步骤:
加载过程:使用(自定义)类加载器去获取类文件字节码字节类的过程,Class实例在这一步生成,作为方法区的各种数据类型的访问入口。
- 验证过程:JVM验证字节码的合法性。
- 准备过程:为类变量分配内存并且设置初始值。
- 解析过程:JVM把常量池中的符号替换为直接引用。
- 初始化过程:执行类构造器<cinit>()方法,<cinit>()方法是编译器自动收集所有类变量的赋值动作和静态代码块中的语句合并生成,收集顺序由语句在源文件中出现的顺序决定,JVM保证在子类<cinit>()方法调用前父类的<cinit>()方法已经执行完毕。
当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。
类加载的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。
2.ClassLoader类的反射加载
Reflection(反射) 是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API 取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。(在程序运行时获取对象)。
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以我们形象的称之为:反射。
延伸阅读
ClassLoader是做什么的
顾名思义,ClassLoader是用来加载Class的。它负责将Class的字节码形式转换成内存形式的Class对象。字节码可以来自于磁盘文件*.class,也可以是jar包里的*.class,也可以来自远程服务器提供的字节流,字节码的本质就是一个字节数组[]byte,它有特定的复杂的内部格式。
有很多字节码加密技术就是依靠定制ClassLoader来实现的。先使用工具对字节码文件进行加密,运行时使用定制的ClassLoader先解密文件内容再加载这些解密后的字节码。每个Class对象的内部都有一个classLoader字段来标识自己是由哪个ClassLoader加载的。ClassLoader就像一个容器,里面装了很多已经加载的Class对象。