当前位置: 移动技术网 > IT编程>开发语言>Java > 荐 双亲委派机制

荐 双亲委派机制

2020年07月16日  | 移动技术网IT编程  | 我要评论

双亲委派机制:

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网