首页 > 编程语言 > 详细

Java类加载和对象创建过程

时间:2021-05-08 00:19:50      阅读:19      评论:0      收藏:0      [点我收藏+]

引言

Java代码需要被使用,必须要经过类加载器加载到内存中,然后对应的类才能够被创建使用,这文对类加载和对象创建和过程进行分析。

类加载

Java类通过懒加载的方式,经过了Loading、Linking、Initializing后加载到内存中,才能被进行使用。
技术分享图片

Loading

懒加载

Java类并不是JVM虚拟机启动的时候,就对所有用到的类进行全部加载,而是在第一次使用到的时候,进行加载
LazyLoading五种情况

  1. new getstatic putstatic invokestatic指令,访问final变量除外
  2. java.lang.reflect对类进行反射调用时
  3. 初始化子类的时候,父类首先初始化
  4. 虚拟机启动时,被执行的主类必须初始化
  5. 动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化

双亲委派

Java类加载的时候,默认情况下,遵循双亲委派的原则(自下向上的查找,自顶向下的加载),为了类安全,核心类不会遭到破坏
技术分享图片
在抽象类ClassLoader里面,通过模板方法的方式,给出了默认未重写情况下的LoadClass方法

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            //先在自己的缓存中查找是否已经加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                     //如果自己没有加载过,就交给父类去加载
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        //Bootstrap加载器的parent变量为空
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    //当交给父类加载器去加载后,如果没有加载到返回了NULL,则自己去进行加载
                    //这个地方会报ClassNotFound异常,但如果还有子加载器的话,则会在上面被捕捉到,如果已经是最子级加载器的话,则直接报异常。
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                //进行解析
                resolveClass(c);
            }
            //返回调用的地方
            return c;
        }
    }

一般情况下,不需要打破双亲委派的,在自定义ClassLoader的时候,只需要重写findClass方法即可。

Java类加载和对象创建过程

原文:https://www.cnblogs.com/yanchuanbin/p/14742602.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!