欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 双亲委派机制

程序员文章站 2022-05-18 19:21:45
双亲委派机制:1.双亲委派机制的优势:①:避免类的重复加载②:保护程序安全,防止核心API被随意修改例如自定义类:java.lang.String说的再多不如直接上代码package java.lang;public class String { static { System.out.println("这是自定义类的String类的静态代码块"); } public static void main(com.cdc.runtime_data_are...

双亲委派机制:

1.双亲委派机制的优势:

①:避免类的重复加载

②:保护程序安全,防止核心API被随意修改

例如自定义类:java.lang.String

说的再多不如直接上代码

package java.lang;

public class String {
    static {
        System.out.println("这是自定义类的String类的静态代码块");
    }

    public static void main(com.cdc.runtime_data_area.classloader.java.lang.String[] args) {
        System.out.println("hello String");
    }
}

可以看到,我在src下定义了一个java.lang.String类,与java自带的java.lang.String是重复的

荐
                                                        双亲委派机制

在这里,我们直接运行里面的main方法:

错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
   public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application

Process finished with exit code 1

可以看到,出了异常,异常信息为在java.lang.String中找不到main方法,这是由于双亲委派机制的,对java的核心API进行了保护,让我们无法对其随意进行更改

之后,又写了一个demo,对该类进行测试

public class StringDemo {


    public static void main(String[] args) {
        java.lang.String str=new java.lang.String();
        System.out.println("hello World");
    }
}

运行结果为:

"C:\Program Files\Java\jdk1.8.0_202\bin\java.exe" "-javaagent:F:\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=53986:F:\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_202\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_202\jre\lib\rt.jar;F:\Java自学\jvm\JVMDemo\out\production\JVMDemo" java.StringDemo
java.lang.SecurityException: Prohibited package name: java
	at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" 
Process finished with exit code 1

在这里,可以看到:java.lang.SecurityException: Prohibited package name: java,说明java这个包名是不能随便定义的。

2.双亲委派机制是如何进行工作的呢(工作原理):

①:如果一个类加载器收到了类加载的请求,它并不会自己先去加载,而是将请求委托给父类的加载器去执行

②:如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终达到顶层的启动类加载器

③:如果父加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成加载任务,子加载器才会去尝试自己加载,这就是双亲委派机制

荐
                                                        双亲委派机制

例如在刚刚的那个代码中,系统类加载器收到类加载的请求,并没有直接加载,而是往上发送委托,由拓展类加载器进行加载,但是拓展类加载器上面还有父类,所以继续向上委托,交给了引导类加载器进行加载。这时,引导类加载器只加载包名为java、javax、sun开头的包名下面的类,发现我们自定义的String类正好是由java开头的,便由他来加载,便不再向下委托。此时我们自定义的String类变成了核心API中的String类,而在核心API中的String类是没有main方法的,因此便报了在类java.lang.String类中找不到main方法的异常。

再举一个生活中的例子:

情况一:有一个苹果,你拿到之后,发现自己母亲在,然后就拿去问:妈妈,你吃不吃苹果啊。这时候母亲又拿着苹果去问奶奶,奶奶一看,这么硬的苹果,我牙都没了咋吃啊。于是就说:我不吃。苹果又到了母亲手上,一看,苹果有点酸,我还是不吃了,又给了你,这时候苹果就成了你的,就由你来吃。

情况二:拿到苹果时,由母亲拿给奶奶,奶奶说,正好想吃一个苹果。这时候苹果就给了奶奶吃,就没下面两人啥事了。

本文地址:https://blog.csdn.net/cdypa/article/details/107336377