JVM详解 -> 类加载器及双亲委派机制
1. 类加载器
-
类装载器的作用:加载Class文件
-
- 虚拟机自带的加载器
- 启动类(根)加载器
- 扩展类加载器
- 应用程序加载器
public class Car { public int age; public static void main(String[] args) { //类是模板,对象是具体的 //new出来的car1、car2、car3在栈里面,栈只是引用变量,具体的数据在堆里。 Car car1 = new Car(); Car car2 = new Car(); Car car3 = new Car(); car1.age = 1; car2.age = 2; car3.age = 3; System.out.println(car1.hashCode()); //460141958 System.out.println(car2.hashCode()); //1163157884 System.out.println(car3.hashCode()); //1956725890 Class<? extends Car> aClass1 = car1.getClass(); Class<? extends Car> aClass2 = car1.getClass(); Class<? extends Car> aClass3 = car1.getClass(); System.out.println(aClass1.hashCode()); //685325104 System.out.println(aClass2.hashCode()); //685325104 System.out.println(aClass3.hashCode()); //685325104 ClassLoader classLoader = aClass1.getClassLoader(); System.out.println(classLoader); //AppClassLoader System.out.println(classLoader.getParent()); //ExtClassLoader \jre\lib\ext System.out.println(classLoader.getParent().getParent()); //null java程序获取不到根加载器 rt.jar } }
2. 双亲委派机制
- 类加载器收到类加载的请求;
- 将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器;
- 启动类加载器检查是否能够加载当前类,能加载就结束,使用当前的加载器,否则,抛出异常通知子加载器进行加载;
- 重复步骤3
- Class Not Found
- Java调用不到启动类加载器,因为其底层是用 C、C++写的
package java.lang;
public class String {
//双亲委派机制:安全
//APP -> EXT -> BOOT(最终执行)
public String toString(){
return "hello";
}
public static void main(String[] args) {
String s = new String();
System.out.println(s.getClass().getClassLoader());
s.toString();
}
}
执行结果:
错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
public static void main(String[] args)
否则 JavaFX 应用程序类必须扩展javafx.application.Application
public class Student {
@Override
public String toString() {
return "Hello";
}
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.toString()); //Hello
System.out.println(student.getClass().getClassLoader()); //sun.misc.Launcher$AppClassLoader@18b4aac2
}
}