JVM中类的生命周期包括7个阶段,加载、准备、验证、解析、初始化、使用、卸载。其中准备、验证、解析被归为链接阶段。java
jvm在这个阶段完成的工做数据结构
java.lang.class
对象,做为访问类在方法区中数据的入口在这个阶段开发者能够控制二进制字节流的获取,也就是能够经过自定义的类加载器作本身定制化的操做。jvm
顾名思义,验证被加载的类的正确性。ide
为类的 静态变量分配内存,并将其初始化为默认值spa
final static
修饰的变量则会赋值为代码中的初始值(即:final static int val=3,这时val赋值为3,而不是0)把类中的符号引用转换为直接引用符号引用就是一组符号来描述目标(例如:ArrayList)。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。指针
类变量的初始化code
触发类初始化的场景对象
sun.misc.Launcher$ExtClassLoader
,它负责加载 jrelibext目录中,或者由 java.ext.dirs系统变量指定的路径中的全部类库。开发者能够直接使用。sun.misc.Launcher$AppClassLoader
,它负责加载用户类路径(ClassPath)所指定的类。开发者能够直接使用双亲委派模型的实现,当一个类加载器须要加载类时,会把这个任务委派给父级类加载器,依次向上,倒顶层启动类加载器为止,若是父级没法加载,再本身处理加载。双亲委派模型的好处是,保证同一类环境中只有一个相同的类。也就是说JVM中判断是不是同一个类的条件是,是否相同的类加载器,类自己相同。代码示例:生命周期
public class ClassLoaderTest { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { // 使用ClassLoaderTest的类加载器加载本类 Object obj1 = ClassLoaderTest.class.getClassLoader().loadClass("com.ognice.ClassLoaderTest").newInstance(); System.out.println(obj1.getClass().getClassLoader()); System.out.println(obj1 instanceof ClassLoaderTest); // 使用自定义类加载器加载本类 ClassLoader customClassLoader = new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { System.out.println("custom classloader loading " + name); String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; InputStream stream = getClass().getResourceAsStream(fileName); if (stream == null) { return super.loadClass(name); } try { byte[] b = new byte[stream.available()]; stream.read(b); return defineClass(name, b, 0, b.length); } catch (IOException e) { e.printStackTrace(); } // 父级找class return super.loadClass(name); } }; Object obj2 = customClassLoader.loadClass("com.ognice.ClassLoaderTest").newInstance(); System.out.println(obj2.getClass().getClassLoader()); System.out.println(obj2 instanceof ClassLoaderTest); } }
执行结果内存
sun.misc.Launcher$AppClassLoader@18b4aac2 true custom classloader loading com.ognice.ClassLoaderTest custom classloader loading java.lang.Object custom classloader loading java.lang.ClassLoader custom classloader loading com.ognice.ClassLoaderTest$1 com.ognice.ClassLoaderTest$1@277c0f21 false