精华内容
下载资源
问答
  • 深入理解双亲委派机制作用

    千次阅读 多人点赞 2020-04-03 16:34:38
    java双亲委派机制作用 一、什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。 二、...

                                                        java双亲委派机制及作用

    一、什么是双亲委派机制

    当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。

    二、类加载器

    BootstrapClassLoader(启动类加载器)

    c++编写,加载java核心库 java.*,构造ExtClassLoader和AppClassLoader。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

    ExtClassLoader (标准扩展类加载器)

    java编写,加载扩展库,如classpath中的jre ,javax.*或者java.ext.dir 指定位置中的类,开发者可以直接使用标准扩展类加载器。

    AppClassLoader(系统类加载器)

    java编写,加载程序所在的目录,如user.dir所在的位置的class

    CustomClassLoader(用户自定义类加载器)

    java编写,用户自定义的类加载器,可加载指定路径的class文件

    三、类加载器的加载路径

    import java.net.URL;
    import java.net.URLClassLoader;
    
    /*
    分析BootstrapClassLoader/ExtClassLoader/AppClassLoader的加载路径
    *
    */
    public class ClassPath_of_Bootstrap_Ext_AppClassLoader {
    
        public static void main(String[] args) {
            System.out.println("BootstrapClassLoader 的加载路径: ");
            URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
            for (URL url : urls) {
                System.out.println(url);
            }
            System.out.println("----------------------------");
    
            //取得扩展类加载器
            URLClassLoader extClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader().getParent();
            System.out.println(extClassLoader);
            System.out.println("扩展类加载器 的加载路径: ");
            urls = extClassLoader.getURLs();
            for (URL url : urls) {
                System.out.println(url);
            }
            System.out.println("----------------------------");
    
    
            //取得应用(系统)类加载器
            URLClassLoader appClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
            System.out.println(appClassLoader);
            System.out.println("应用(系统)类加载器 的加载路径: ");
            urls = appClassLoader.getURLs();
            for (URL url : urls) {
                System.out.println(url);
            }
            System.out.println("----------------------------");
        }
    }

    这些都是打印出来的结果,不如再进入源码看一下

    public class Launcher {
    //启动类加载器加载的路径
    private static String bootClassPath = System.getProperty("sun.boot.class.path");
    //扩展类加载器加载的路径
    String var0 = System.getProperty("java.ext.dirs");
    //系统类加载器加载的路径
    final String var1 = System.getProperty("java.class.path");
    } 
    

    现在我们就知道了这三个类加载器的加载路径了:

    • BootstrapClassLoader启动类加载器                     ---加载jre/目录下的核心库
    • ExtClassLoader扩展类加载器                               ---加载/jre/lib/ext/目录下的扩展包
    • AppClassLoader应用(系统)类加载器                    ---加载classpath路径下的包
       

    三、源码了解

    protected Class<?> loadClass(String name, boolean resolve)
                throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // 首先检查这个classsh是否已经加载过了
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        // c==null表示没有加载,如果有父类的加载器则让父类加载器加载
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                            //如果父类的加载器为空 则说明递归到bootStrapClassloader了
                            //bootStrapClassloader比较特殊无法通过get获取
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {}
                    if (c == null) {
                        //如果bootstrapClassLoader 仍然没有加载过,则递归回来,尝试自己去加载class
                        long t1 = System.nanoTime();
                        c = findClass(name);
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                    }
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }

    委派机制的流程图

    • 首先判断了该类是否已加载.
    • 若没加载,则传给双亲加载器去加载,
    • 若双亲加载器没能成功加载它,则自己用findClass()去加载.所以是个向上递归的过程.
    • 自定义加载器时,需要重写findClass方法,因为是空的,没有任何内容:
    protected Class<?> findClass(String name) throws ClassNotFoundException {
         throw new ClassNotFoundException(name);
    }

    四、双亲委派机制的作用

    1、保证安全性

            防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。

    2、保证唯一性

            保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

    试想,如果没有双亲委派模型而是由各个类加载器自行加载的话,如果用户编写了一个java.lang.Object的同名类并放在ClassPath中,多个类加载器都去加载这个类到内存中,系统中将会出现多个不同的Object类,那么类之间的比较结果及类的唯一性将无法保证,因为Object都各不相同那么程序运行启动就会出错,也保证了JVM能够正常的安全运行。

     

     

     

     

    展开全文
  • jvm的双亲委派机制作用 什么是双亲委派机制 当某个类加载器需要加载某个**.class文件时,它首先把这个任务委托给他的上级类加载器**,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类,有就加载...

    jvm的双亲委派机制及作用

    什么是双亲委派机制

    当某个类加载器需要加载某个**.class文件时,它首先把这个任务委托给他的上级类加载器**,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类,有就加载。

    类加载器可分为两类

    • 一是启动类加载器(Bootstrap ClassLoader),是C++实现的,是JVM的一部分;
    • 另一种是其它的类加载器,是Java实现的,独立于JVM,全部都继承自抽象类java.lang.ClassLoader。
    • jdk自带了三种类加载器,分别是启动类加载器(Bootstrap ClassLoader),扩展类加载器(Extension ClassLoader),应用程序类加载器(Application ClassLoader)。后两种加载器是继承自抽象类java.lang.ClassLoader

    类加载器是有层次的

    一般是: 自定义类加载器 >> 应用程序类加载器 >> 扩展类加载器 >> 启动类加载器
    上面的层次关系被称为双亲委派模型(Parents Delegation Model)。除了最顶层的启动类加载器外,其余的类加载器都有对应的父类加载器。
    再简单说下双亲委托机制:
    如果一个类加载器收到了类加载的请求,它首先不会自己尝试去加载这个类,而是把这个请求委派给父类加载器,每一个层次的类加载器都是加此,因此所有的加载请求最终到达顶层的启动类加载器,只有当父类加载器反馈自己无法完成加载请求时(指它的搜索范围没有找到所需的类),子类加载器才会尝试自己去加载。

    测试是否能自定义java.lang.System类

    测试代码没用自定义java.lang.System类,因为测试代码用到了JDK自带的System类进行输出打印,会冲突,所以改用为自定义的java.lang.Math类。如果自定义的Math类能加载,那么自定义的System类同样能加载。
    我们先直接运行下Math类,输出如下:

    java.lang.NoSuchMethodError: main
    Exception in thread "main" 
    • 提示Math类没有main方法。首先大家要明白一个概念,当类首次主动使用时,必须进行类的加载,这部分工作是由类加载器来完成的。根据双亲委托原则,Math类首先由启动类加载器去尝试加载,很显然,它找到rt.jar中的java.lang.Math类并加载进内存并不会加载我们自定义的Math类),然后执行main方法时,发现java.lang.Math类不存在该方法,所以报方法不存在错误。也就是说,默认情况下JVM不会加载我们自定义的Math类
    • 直接查看抽象类java.lang.ClassLoader的preDefineClass方法代码,可以看到代码就写了如果加载的类全名称以“java.”开头时,将会抛出SecurityException,这也是为什么直接执行MyMath类会出现SecurityException。
      照这样,我们自定义的类加载器必须继承自ClassLoader,其loadClass()方法里调用了父类的defineClass()方法,并最终调到preDefineClass()方法,因此我们自定义的类加载器也是不能加载以“java.”开头的java类的。

    这个详细,很猛

    展开全文
  • 双亲委派机制以及打破双亲委派机制 双亲委派机制 Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存中生成class对象,而且加载某个类的class文件时,Java虚拟机...

    双亲委派机制以及打破双亲委派机制

    双亲委派机制

    Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存中生成class对象,而且加载某个类的class文件时,Java虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任务委派模式.

    双亲委派机制的优点:

    • 1、避免类的重复加载
    • 2、保护程序的安全性,防止核心API随意被篡改
      在这里插入图片描述
      在这里插入图片描述

    沙箱安全机制:保证对Java信息源代码的保护

    何为沙箱安全机制?即如果我们自己建立和源代码相同的包,例如java/lang/String.Class,在我们去使用类加载器去加载此类时,为了防止你自定义的类对源码的破坏,所以他默认不是使用你的String类的本身的系统加载器去加载它,而是选择率先使用引导类加载器去加载,而引导类在加载的过程中会先去加载JDK自带的文件(rt.jar包中的java/lang/String.class),而不是你自己定义的String.class,报错信息会提示没有main方法 ,就是因为加载的是rt.jar包下的String类,这样就可以做到保证对java核心源代码的保护,这即是沙箱保护机制.

    那么双亲委派机制存在哪些缺点,又有哪些打破双亲委派机制的例子呢?

    通过上面双亲委派机制的特点,我们知道了以下结论:

    由于BootStrapClassLoader是顶级类加载器,并且它不能使用AppClassLoader加载器加载的类,因为BootstrapClassloader无法委派AppClassLoader来加载类。故当我们的上层类加载器需要下层类加载器帮忙加载类,就会出现问题,这便是双亲委派机制的缺点,那么哪些场景发生了这些事情,而Java又是如何打破这种双亲委派机制的呢?

    我们来举一个经典的打破双亲委派机制的例子:Java SPI机制

    SPI(Service Provider Interface),主要是应用于厂商自定义组件或插件中。

    java SPI提供一种服务发现的机制,即为某个接口寻找服务实现的机制,我们在需要在jar包的META-INF/services/目录里面创建一个一服务接口命令的文件,而该文件就是实现这个接口的具体实现类,当有外部程序需要装配我们的这个模块接口的时候,就可以通过META-INF/services/目录的配置文件找到对应的实现类的类名,并将其实例化,完成该接口模块的注入。而在JDK中,也提供了一个服务实现查找的一个工具类:java.util.ServiceLoader。

    我们以数据库连接jar包为例:mysql-connector-java-5.1.37.jar,它遵循SPI的规范

    在这里插入图片描述

    我们的java.sql.Driver接口定义在java.sql包下,而该包的位置位于jdk\jre\lib\rt.jar,其中java.sql包中还提供了其它相应的类和接口比如管理驱动的类:DriverManager类等等,这样我们就很清楚地知道了java.sql是由BootStrapClassLoader加载器加载的

    而我们的接口的实现类com.mysql.jdbc.Driver是第三方实现的类库,是由AppClassLoader加载器加载的

    那么问题来了:我们使用DriverManager获取Connection的时候,必然会加载到com.mysql.jdbc.Driver类,此时即是BootstrapClassloader加载的类使用了由AppClassLoader加载的类,很明显和双亲委托机制的原理相悖!!!

    JVM采取了一种作弊的方式打破了双亲委派机制,从而完成了上层类加载器使用下层类加载器进行加载的类:

    在BootstrapClassLoader或ExtClassLoader加载的类A中,如果使用到AppClassLoader类加载器加载的类B,由于双亲委托机制不能向下委托,那可以在类A中通过线程上下文类加载器获得AppClassLoader,从而去加载类B

    我们通过源码来看一下:

    首先我们创建一个web项目,然后导入mysql的驱动包,我们编写一下测试代码:

    public class TestClassLoader {
        public static void main(String[] args) throws SQLException, ClassNotFoundException {
            String driverClassName = "com.mysql.jdbc.Driver";
            String url = "jdbc:mysql://localhost:3306/mybatis";
            String username = "root";
            String password = "root";
            Connection connection = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
    
            //执行驱动"com.mysql.jdbc.Driver"
            Class.forName("com.mysql.jdbc.Driver");
    
            //获取连接
            connection = DriverManager.getConnection(url,username,password);
        }
    }
    

    此时我们知道这段代码肯定是能正常执行了,第一步加载我们的mysql的驱动,然后利用DriverManager获取连接

    那么我们将第一步的执行驱动代码注释掉,你猜猜还会执行成功吗??
    根据上面我们说的,答案是肯定的!!!我们进入源码探究一下

    DriverManager类的内部存在一个静态代码块,其中有一个**loadInitialDrivers()**方法:

    在这里插入图片描述

    我们点进去,里面有一行代码:

    //JDK中提供的ServiceLoader来实现服务实现查找功能
    ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
    

    在这里插入图片描述

    我们点进去这个方法看看:

    public static <S> ServiceLoader<S> load(Class<S> service) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        return ServiceLoader.load(service, cl);
    }
    

    这段代码便是打破双亲委派机制,实现com.mysql.jdbc.Driver驱动类加载的核心,即我们获取线程上下文加载器Thread.currentThread().getContextClassLoader(),然后利用线程上下文类加载器进行mysql驱动的类加载,以达到打破双亲委派机制的作用

    PS:此时如果我们改变线程上下文类加载器,就会使得此时程序出现错误,大家也就明白了其中的流程和原理了

    public class TestClassLoader {
        public static void main(String[] args) throws SQLException, ClassNotFoundException {
            String driverClassName = "com.mysql.jdbc.Driver";
            String url = "jdbc:mysql://localhost:3306/mybatis";
            String username = "root";
            String password = "root";
            Connection connection = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
    
            //改变当前线程上下文类加载器为当前类的扩展类加载器
            Thread.currentThread().setContextClassLoader(TestClassLoader.class.getClassLoader().getParent());
            
            //执行驱动"com.mysql.jdbc.Driver"
            //Class.forName("com.mysql.jdbc.Driver");
    
            //获取连接
            connection = DriverManager.getConnection(url,username,password);
        }
    }
    

    执行结果:

    Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/mybatis
    	at java.sql.DriverManager.getConnection(DriverManager.java:689)
    	at java.sql.DriverManager.getConnection(DriverManager.java:247)
    	at it.feng.test.TestClassLoader.main(TestClassLoader.java:25)
    
    展开全文
  • 双亲委派机制及打破双亲委派示例

    千次阅读 2021-01-01 20:22:03
    双亲委派机制 在加载类的时候,会一级一级向上委托,判断是否已经加载,从自定义类加载器-》应用类加载器-》扩展类加载器-》启动类加载器,如果到最后都没有加载这个类,则回去加载自己的类。 双亲委托有个弊端...

    双亲委派机制

    在加载类的时候,会一级一级向上委托,判断是否已经加载,从自定义类加载器-》应用类加载器-》扩展类加载器-》启动类加载器,如果到最后都没有加载这个类,则回去加载自己的类。

    双亲委托有个弊端:

    不能向下委派,不能不委派

    怎么打破双亲委派机制:(也就是能向下委派和不委派)

    自定义类加载器(不委派)

    spi机制(向下委派)

    打破双亲委派

    打破双亲委派的两种方式:

    1.通过spi机制,使用ServiceLoader.load去加载

    2.通过自定义类加载器,继承classloader,重写loadclass方法

    SPI机制

    spi机制是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。这一机制为很多框架扩展提供了可能,比如在JDBC中就使用到了SPI机制。

    为什么通过spi机制就能打破双亲委托?

    因为在某些情况下父类加载器需要委托子类加载器去加载class文件。受到加载范围的限制,父类加载器无法加载到需要的文件。

    以Driver接口为例,DriverManager通过Bootstrap ClassLoader加载进来的,而com.mysql.jdbc.Driver是通过Application ClassLoader加载进来的。由于双亲委派模型,父加载器是拿不到通过子加载器加载的类的。这个时候就需要启动类加载器来委托子类来加载Driver实现,从而破坏了双亲委派。

    SPI机制demo:

    public interface HelloService {
        public String getName();
    }
    public class Hello1 implements HelloService{
        @Override
        public String getName() {
            return "hello1";
        }
    }
    public class Hello2 implements HelloService{
        @Override
        public String getName() {
            return "hello2";
        }
    }
    

    来一个main方法去加载它,将使用ServiceLoader来进行加载

    public class SPITest {
        public static void main(String[] args) {
            ServiceLoader<HelloService> serviceLoader = ServiceLoader.load(HelloService.class);
            for (HelloService helloService :serviceLoader){
                System.out.println(helloService.getName());
            }
        }
    }

    配置文件,文件名为接口的全路径,文件内容为实现类的全路径,如我的为:com.chuan.service.Hello1

    输出结果:hello1

    只配置了Hello1,所以只发现了这一个实现类。

    自定义类加载器

    实现逻辑:自定义类继承classLoader,作为自定义类加载器,重写loadClass方法,不让它执行双亲委派逻辑,从而打破双亲委派。

    先看一个没有重写的demo

    结果:

    sun.misc.Launcher$AppClassLoader@58644d46

    发现是app类加载器。

    然后重写loadClass方法

    public class MyClassLoader extends ClassLoader{
        public static void main(String[] args) throws ClassNotFoundException {
            // ServiceLoader.load()
            MyClassLoader myClassLoader = new MyClassLoader();
            Class<?> aClass = myClassLoader.loadClass(Test1.class.getName());
            System.out.println(aClass.getClassLoader());
        }
        protected Class<?> findClass(String className) throws ClassNotFoundException {
            System.out.println("My findClass!");
            return null;
        }
    
        protected Class<?> loadClass(String name, boolean resolve)
                throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        //修改classloader的原双亲委派逻辑,从而打破双亲委派
                        if (name.startsWith("com.chuan")){
                            c=findClass(name);
                        }
                        else {
                            c=this.getParent().loadClass(name);
                        }
                    } catch (ClassNotFoundException e) {
                    }
    
                    if (c == null) {
                        long t1 = System.nanoTime();
                        c = findClass(name);
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                    }
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }
    }
    class Test1{
    
            }

    运行报错,因为没有委派给app类加载器,所以找不到加载不了这个类。

    那么新的问题又来了,如果我自定义类记载器和核心类重名怎么办,该怎么加载,又或者我想篡改核心类内容,jvm又是怎么解决的?

    jvm肯定解决了这个问题,openjdk源码在AccessController.doPrivileged

    学名叫做沙箱安全机制,主要作用是:保护核心类,防止打破双亲委派机制,防篡改,如果重名的话就报异常,这里的重名指包名加类名都重复。

    demo:

    package java.lang;
    
    public class Integer {
        public static void main(String[] args) {
            System.out.println("1");
        }
    }

    运行报错:

    错误: 在类 java.lang.Integer 中找不到 main 方法, 请将 main 方法定义为:

    public static void main(String[] args)

    否则 JavaFX 应用程序类必须扩展javafx.application.Application

     

    展开全文
  • 什么是Java的双亲委派
  • 双亲委派机制

    2020-07-29 08:30:34
    双亲委派机制 一、什么是双亲委派机制 每个类加载器都有自己的一个加载路径,当某个类加载器需要加载某个.class文件时,它不是立刻从自己的加载路径中去找这个class文件,而是委派给它的父类加载器去加载。它的...
  • JAVA中双亲委派机制的原理及其作用 什么是双亲委派 当某个类要去加载的时候先去父类里看看这个类有没有被加载过,没有的话再去父类的父类去找,有点类似于递归查找,如果没有的话再自己加载。 有些什么类加载器 ...
  • JVM双亲委派机制详解

    2020-10-25 23:13:45
    JVM双亲委派机制详解前言学习后可以解决的问题类加载器的分类分类每个类加载器的作用启动类加载器扩展类加载器应用程序类加载器自定义类加载器解决方法:双亲委派包含内容向上委派如何理解向上委派?向上委派的过程...
  • 双亲委派机制作用 2.1 什么是双亲委派机制 当某个类加载器要加载 .class文件时,先上级类加载器去加载,一直递归下去,如果上级类加载器没有加载,则自己在去加载。 2.2 类加载器的区别 启动类加载器 ...
  • Java中的双亲委派机制以及如何打破

    千次阅读 2020-07-31 18:51:55
    Java中的双亲委派机制以及如何打破 什么是双亲委派机制 当一个类收到了类的加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一层的类加载器都是如此,因此所有的加载请求都应该传送到...
  • 今天要谈一谈在面试过程中几乎被每个面试官都会提到的一个问题——java中双亲委派机制作用?  由于我也是刚刚学习编程的小白,所以此篇博文将参考了多篇博文,最后总结而成。 1.什么是双亲委派机制  当某个类...
  • 双亲委派机制   双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此(递归的去查找),只有在父类加载器在自己的搜索范围内找不到指定类时,子类...
  • 双亲委派机制作用1、保证安全性2、保证唯一性 1.什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去...
  • 什么是双亲委派机制双亲委派机制指的是当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个加载器都是如此,只有在父类加载器在自己 的搜索范围内找不到指定类时,子类加载器才会...
  • 双亲委派机制时JVM类加载的默认使用的机制,其原理是:当一个类加载器收到类加载任务时,会先交给自己的父加载器去完成,因此最终加载任务都会传递到最顶层的BootstrapClassLoader,只有当父加载器无法完成加载任务时...
  • classLoader双亲委派机制

    千次阅读 2019-06-10 19:14:23
    初始化这个Integer的构造器是会退出JVM,破坏应用程序的正常进行,如果使用双亲委派机制的话该Integer类永远不会被调用,以为委托BootStrapClassLoader加载后会加载JDK中的Integer类而不会加载自定义的这个,可以看...
  • JAVA双亲委派机制

    2020-11-01 14:16:31
    JAVA双亲委派机制 什么是双亲委派机制 java在类加载时有几种机制,其中一种就是双亲委派机制。 类加载器收到类加载的请求 将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器。 启动加载器检查...
  • 双亲委派机制 类的生命周期 类从被加载到虚拟机开始,到卸载出内存为止,它的整个的生命周期包括:加载、连接(验证、准备、解析)、初始化、使用和卸载七个阶段。 加载过程 将编译之后的Class文件加载...
  • 双亲委派机制的原理及好处

    千次阅读 2020-01-20 16:17:34
    原理:当一个类加载器收到加载类的任务时,会先让父类加载器去加载,父类加载器也会优先让本身的父类加载器去加载,依次类推,直至启动类加载器。 好处:这样做的好处就是避免类的重复加载,保护了核心的API库。...
  • } } 其中这几句代码的作用就是实现了双亲委派机制,很明显他的意思是如果父加载器不为空就调用父类加载器,如果父类加载器为空就使用引导类BootstrapClass加载器加载,我们将这端代码删除就可以打破双亲委派机制了...
  • 怎么打破双亲委派机制

    万次阅读 2018-08-14 20:47:26
    双亲委派模型的作用  作用:保证JDK核心类的优先加载; 如何打破双亲委派模型? 自定义类加载器,重写loadClass方法; 使用线程上下文类加载器; 双亲委派模型破坏史 1.第一次破坏 由于双亲...
  • 双亲委派模式的优点

    万次阅读 多人点赞 2019-06-06 16:39:17
    解释:为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。而System类是Bootstrap加载器加载的,就算自己重写,也总是使用Java系统提供的System,自己写...
  • 一、类加载器(Class Loader) ...试想,如果没有双亲委派机制模型而是由各个类加载器自行加载的话,如果用户编写了一个java.lang.Object的同名类并放在ClassPath中,多个类加载器都会去加载这个类到内存中,系统中将
  • } } 双亲委派机制双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器。每个类加载器都是如此,只有在父类加载器在自己的搜索范围内找不到指定类时,子类加载器才会...
  • 双亲委派机制的由来

    2020-10-06 18:41:20
    什么是双亲委派机制? 首先我们通过一个简单的例子来理解以下,首先我们先来理解委派机制,顾名思义委派就相当于一个用户委派快递员寄快递,这个过程是单项的,不可能换成快递员委派用户来寄快递。然后我们再理解...
  • Java类加载器和双亲委派机制

    千次阅读 2019-02-09 00:55:50
    loadClass()方法是一个类加载的主要方法,从代码中我们可以看出该类加载器进行类加载的操作集中在findClass()方法中,loadClass()方法其余的代码都是在维护双亲委派机制,所以我们在实现自己的类加载器时只需重新...
  • 最近在重读《深入理解Java虚拟机》,看到破坏双亲委派这一块内容时,通过对JDBC驱动加载过程源码debug,突然茅塞顿开,收获不少,以前仅仅只是知道概念,特此记录一下 也看了一些其他博主的文章,虽然最后还是搞明白...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,791
精华内容 6,716
关键字:

双亲委派机制作用