JVM16_类的概述、分类、ClassLoader源码分析、自定义类的加载器、双亲委派机制、沙箱安全机制(四)

简介: ②. 抽象类ClassLoader的主要方法(内部没有抽象方法)③. SecureClassLoader与URLClassLoader④. Class.forName()与ClassLoader.loadClass()对比

②. 抽象类ClassLoader的主要方法(内部没有抽象方法)


①. public final ClassLoader getParent():返回该类加载器的超类加载器


②. public Class<?> loadClass(String name) throws ClassNotFoundException

(加载名称为name的类,返回结果为java.lang.Class类的实例。如果找不到类,则返回ClassNot FoundException 异常。该方法中的逻辑就是双亲委派模式的实现)


③. protected Class<?> findClass (String name) throws ClassNotFoundException

查找二进制名称为name的类,返回结果为java.lang.Class类的实例。这是一个受保护的方法,JVM鼓励我们重写此方法,需要自定义加载器遵循双亲委托机制,该方法会在检查完父类加载器之后被loadClass()方法调用。


④. protected final Class<?> defineClass(String name, byte[] b, int off, int len)

根据给定的字节数组b转换为Class的实例,off和len参数表示实际Class信息在byte数组中的位置和长度,其中byte数组b是ClassLoader从外部获取的。这是受保护的方法,只有在自定义ClassLoader子类中可以使用。


⑤. protected final void resolveClass(Class<?> c)

链接指定的一个Java类。使用该方法可以使用类的Class对象创建完成的同时也被解析。前面我们说链接阶段主要是对字节码进行验证,为类变量分配内存并设置初始值同时将字节码文件中的符号引用转换为直接引用


⑥. 源码解析Classloader方法


 测试代码:
 ClassLoader.getSystemClassLoader().loadClass("com.xiaozhi.java.User");
 //resolve==true,加载class的同时需要进行解析操作
 protected Class<?> loadClass(String name, boolean resolve) 
        throws ClassNotFoundException
    {
    //同步操作,保证只能加载一次
        synchronized (getClassLoadingLock(name)) {
            // 在缓存中判断是否已经加载同名的类
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
          //获取当前类的父类加载器
                    if (parent != null) {
            //如果存在父类加载器,则调用父类加载器进行类的加载(双亲委派机制)
                        c = parent.loadClass(name, false);
                    } else {
            //parent==null 父类加载器是引导类加载器
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
        // 当前类的加载器的父类加载器未加载此类 or 当前类的加载器未加载此类
                if (c == null) {
                    // 调用当前classloader的findClass
                    long t1 = System.nanoTime();
                    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;
        }
    }


③. SecureClassLoader与URLClassLoader


①. 接着SecureClassLoader扩展了 ClassLoader,新增了几个与使用相关的代码源(对代码源的位置及其证书的验证)和权限定义类验证(主要指对class源码的访问权限)的方法,一般我们不会直接跟这个类打交道,更多是与它的子类URLClassLoader有所关联


②. 前面说过,ClassLoader是一个抽象类,很多方法是空的没有实现,比如 findClass()、findResource()等。而URLClassLoader这个实现类为这些方法提供了具体的实现。并新增了URLClassPath类协助取得Class字节码流等功能。在编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承URLClassLoader类,这样就可以避免自己去编写findClass()方法及其获取字节码流的方式,使自定义类加载器编写更加简洁


④. Class.forName()与ClassLoader.loadClass()对比


①. Class.forName():是一个静态方法,最常用的是Class.forName(String className);根据传入的类的全限定名返回一个 Class 对象。该方法在将 Class 文件加载到内存的同时,会执行类的初始化。如:Class.forName(“com.atguigu.java.HelloWorld”);


②. ClassLoader.loadClass():这是一个实例方法,需要一个 ClassLoader 对象来调用该方法。该方法将 Class 文件加载到内存时,并不会执行类的初始化,直到这个类第一次使用时才进行初始化。该方法因为需要得到一个 ClassLoader 对象,所以可以根据需要指定使用哪个类加载器。


相关文章
|
26天前
|
存储 缓存 Java
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
34 1
|
8天前
|
监控 Java 关系型数据库
JVM工作原理与实战(十三):打破双亲委派机制-线程上下文类加载器
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了打破双亲委派机制的方法、线程上下文类加载器等内容。
12 2
|
1月前
|
安全 前端开发 Java
【JVM】双亲委派机制详细解读(通俗易懂)
【JVM】双亲委派机制详细解读(通俗易懂)
98 0
|
2月前
|
安全 Java 程序员
深入理解jvm - 类加载过程
深入理解jvm - 类加载过程
50 0
|
存储 安全 算法
深入剖析JVM内存管理与对象创建原理
JVM内存管理,JVM运行时区域,直接内存,对象创建原理。
40 2
|
1月前
|
存储 算法 安全
【JVM】深入理解JVM对象内存分配方式
【JVM】深入理解JVM对象内存分配方式
26 0
|
1月前
|
Java 程序员
探讨JVM垃圾回收机制与内存泄漏
探讨JVM垃圾回收机制与内存泄漏
|
2月前
|
存储 缓存 算法
深入剖析Java中JVM的内存模型!!!
对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。
49 1
|
26天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
68 0
|
12天前
|
存储 前端开发 安全
JVM内部世界(内存划分,类加载,垃圾回收)(上)
JVM内部世界(内存划分,类加载,垃圾回收)
46 0