JVM 1.类的加载、链接、初始化

Java类的加载是由类加载器来完成的,过程以下:java

首先,加载是把硬盘、网络、数据库等的class文件中的二进制数据加载到内存的过程,而后会在Java虚拟机的运行时数据区的堆区建立一个Class对象,用来描述该类,再在方法区存放这些二进制数据,用来保存类对应的数据结构数据库

 

Java的类加载器有哪些?bootstrap

下面的String对象是由bootstrap根类加载器加载的,而自定义类C是由系统加载器加载的:网络

/**
 * 源文档中这样描述:
 *     Some implementations may use null to represent the bootstrap class loader. 
 *         This method will return null in such implementations 
 *         if this class was loaded by the bootstrap class loader.
 * @author Administrator
 *
 */
public class ClassLoader2 {

    //测试
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Class.forName("java.lang.String");
        System.out.println("String类的加载器:"+c1.getClassLoader());//bootstrap根类加载器(C++实现的),返回null
        Class c2 = Class.forName("com.mlxs.classloader.MyClass");
        System.out.println("自定义MyClass类的加载器:"+c2.getClassLoader());//AppClassLoader 系统(应用)加载器
        /**
         * 返回数据:
         *     String类的加载器:null
         *    自定义MyClass类的加载器:sun.misc.Launcher$AppClassLoader@425224ee
         */
    }

}

class MyClass{
    
}

关于初始化,什么状况下初始化类?在主动使用的时候初始化:数据结构

 

一个例子:测试

public class ClassLoader1 {

    private static ClassLoader1 classLoader1 = new ClassLoader1();
    private ClassLoader1(){
        a ++;
        b ++;
    }
    public static int a;
    public static int b = 0;
    public static ClassLoader1 getIntsance(){
        return classLoader1;
    }
    
    //测试
    public static void main(String[] args) {
        ClassLoader1 clazz = ClassLoader1.getIntsance();
        /**
         * 类加载后,
         *     准备阶段:(1)classLoader1赋值null,(2)a和b都赋值默认值0;
         *  初始化阶段: (1)new classLoader1的时候,a++(=1),b++(=1)
         *            (2)a没默认值,值不变;b默认值为0,b赋值0
         * 因此,最后a=1,b=0
         * 
         * 若是把new ClassLoader1()放到int a b 的后面,则最后a=1,b=1 */
        System.out.println("a:"+clazz.a);
        System.out.println("b:"+clazz.b);
    }

}

结果:this

a:1
b:0

  

要注意的是:spa

子类主动使用,会致使父类的初始化;而父类主动使用,不会使子类初始化。如,new Object() 不会致使它的子类(全部的Java类)都初始化code

而子类实现接口,当子类被初始化,不会致使接口初始化。只有当接口中的静态变量被使用时才会初始化对象

相关文章
相关标签/搜索