双亲委派机制。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回(返回的是java.lang.Class的类对象);只有父类加载器无法完成此加载任务时,才自己去加载。委托机制的意义— 防止内存中出现多份同样的字节码
Java类(并非对象)加载分为:加载,链接,初始化:
加载:
Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类 的对象。类加载器需要完成的最终功能是定义一个Java类,即把Java字节代码转换成JVM中的java.lang.Class类的对象。加载时有双亲委派机制。
在JVM中,判断两个类是否相同,不仅是根据该类的二进制名称,还需要根据两个类的定义类加载器。只有两者完全一样,才认为两个类的是相同的。因此,即便是同样的Java字节代码,被两个不同的类加载器定义之后,所得到的Java类也是不同的。
链接:
Java类的链接指的是将Java类的二进制代码合并到JVM的运行状态之中的过程。在链接之前,这个类必须被成功加载。类的链接包括验证、准备和解析等几个步骤。验证是用来确保Java类的二进制表示在结构上是完全正确的。如果验证过程出现错误的话,会抛出java.lang.VerifyError错误。准备过程则是创建Java类中的静态域,并将这些域的值设为默认值。准备过程并不会执行代码。在一个Java类中会包含对其它类或接口的形式引用,包括它的父类、所实现的接口、方法的形式参数和返回值的Java类等。解析的过程就是确保这些被引用的类能被正确的找到。解析的过程可能会导致其它的 Java类被加载。在这个时候,JVM就是通过调用当前类的定义类加载器的loadClass()方法来加载其它类的。
初始化:
当一个Java类第一次被真正使用到的时候,JVM会进行该类的初始化操作。初始化过程的主要操作是执行静态代码块和初始化静态域。在初始化的时候,会按照源代码中从上到下的顺序依次执行静态代码块和初始化静态域。静态代码块只跑一次(多个实例)。
Java对象的初始化过程:
父类静态块->子类静态块->父类构造块->父类构造函数->子类构造块->子类构造函数。
Java类和接口的初始化只有在特定的时机才会发生,这些时机包括:
创建一个Java类的实例。如 MyClassobj = new MyClass()
调用一个Java类中的静态方法。如 MyClass.sayHello()
给Java类或接口中声明的静态域赋值。如 MyClass.value= 10
访问Java类或接口中声明的静态域,并且该域不是常值变量。如 int value = MyClass.value
类加载有三种方式:
1、命令行启动应用时候由JVM初始化加载 //普通类的加载(含import类)
2、通过Class.forName()方法动态加载 //反射类的加载,加载静态代码块
3、通过ClassLoader.loadClass()方法动态加载,不加载静态代码块。
有一篇写的更详细的文章:
见引用:
http://blog.youkuaiyun.com/xhh198781/article/details/6338458