荐 双亲委派机制
程序员文章站
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
推荐阅读
-
[五]类加载机制双亲委派机制 底层代码实现原理 源码分析 java类加载双亲委派机制是如何实现的
-
荐 双亲委派机制
-
荐 浅谈Java中类和对象的初始化、实例化以及方法重载的底层机制
-
图解JVM类加载机制和双亲委派模型
-
【java基础】面试常见问题:类和对象,封装继承多态,final关键字,static关键字,类加载过程,双亲委派模型
-
【java】【16】双亲委派
-
荐 【JVM】JVM类加载机制(类加载过程和类加载器)
-
荐 JavaScript闭包(1):闭包的形成机制梳理
-
Java类加载器( CLassLoader ) : 神秘的双亲委托机制
-
荐 2 自动内存管理机制(一)运行时数据区域、垃圾回收算法和垃圾回收器