做网站之前需要准备什么条件,网站里 动效是用什么做的,网站后台管理系统域名,wordpress 导购按钮在之前的JVM类加载器篇中说过#xff0c;各个类加载器都有自己加载的范围#xff0c;比如引导类加载器只加载Java核心库中的class如String#xff0c;那如果用户自己建一个包名和类名与String相同的类#xff0c;会不会被引导类加载器加载。可以通过如下代码测试#xff0…在之前的JVM类加载器篇中说过各个类加载器都有自己加载的范围比如引导类加载器只加载Java核心库中的class如String那如果用户自己建一个包名和类名与String相同的类会不会被引导类加载器加载。可以通过如下代码测试通过执行结果中的报错信息可以发现JVM实际上加载了rt.jar中的String类并未加载自定义的String这个就是JVM的双亲委派模型解决的问题之一。
package java.lang;public class String {static {System.out.println(自定义String);}public static void main(String[] args) {System.out.println(1);}
}运行结果
错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application双亲委派工作原理
JVM对class文件是按需加载在加载class的过程如果当前类加载器存在父类加载器都会将加载请求先委派给父类加载器这种任务委派方式被称为双亲委派。 在前面的篇章中说过类加载器之间存在非继承的层次关系如下图这种层次关系让类加载器加载的类也具有优先级也就是前面示例中rt.jar中的String优于自定义String的加载这种优先级加载详细原理如下
当一个类加载器收到加载请求他并不会自己加载而是把加载请求委托给父类加载器。如果父类加载器也存在父类加载器继续向上委托如此递归直至最顶层引导类加载器。如果父类加载器能完成类的加载就正常返回反之由子类进行加载递归依次向下。
优点
1、避免全限定名相同的类被重复加载导致程序异常。
2、保护程序防止核心库API被篡改。
三、Java源码实现 双亲委派是在ClassLoader的loadClass()方法中实现代码很少作用很强大源码如下。
protected Class? loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass? c findLoadedClass(name);if (c null) {long t0 System.nanoTime();try {// 实现委派if (parent ! null) {c parent.loadClass(name, false);} else {c findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c null) {// If still not found, then invoke findClass in order// to find the class.long t1 System.nanoTime();c findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}
}SPI机制打破双亲委派
SPI(Service Provider Interface)是一种服务发现机制它通过在ClassPath路径下的META-INF/services文件夹查找文件自动加载文件里所定义的类如JDBC驱动。如下图SPI核心类定义在rt.jar中如java.lang.Driver接口所以本身是由启动类加载器加载当调用SPI接口的实现类时启动类加载器是无法加载实现类的这个时候就提供了线程上下文类加载器(Thread Context ClassLoader)加载实现类ThreadContextClassLoader是可以通过java.lang.Thread#setContextClassLoader方法设置如果没有设置默认为ApplicationClassLoader,这样双亲委派模型中ApplicationClassLoader-BootStrapClassLoader的委派变成了BootStrapClassLoader-ApplicationClassLoader的委派这样就打破了双亲委派的类加载模式。