类加载器
类加载器:加载class文件
类加载器分为好几个,首先它有一些等级
1、虚拟机自带的加载器
2、启动类(根)加载器
3、扩展类加载器
4、应用程序加载器
public class Car {
public static void main(String[] args) {
Car car1 = new Car();
Class<? extends Car> aClass = car1.getClass();
ClassLoader classLoader = aClass.getClassLoader();
System.out.println(classLoader);
}
}
通过car1.getClass获取Car Class,在通过classLoader获取它的类加载器。最后输出一下,查看打印结果
可以看到输出了一个AppClassLoader,也就是应用程序加载器。
接下来我们输出classLoder的父类及祖父类
public class Car {
public static void main(String[] args) {
Car car1 = new Car();
Class<? extends Car> aClass = car1.getClass();
ClassLoader classLoader = aClass.getClassLoader();
System.out.println(classLoader);//AppClassLoader
System.out.println(classLoader.getParent());//ExtClassLoader
System.out.println(classLoader.getParent().getParent());//null
}
}
输出结果:
为什么祖父类是null? 两种情况
1、不存在
2、Java程序获取不到
这里是java运行是的环境,其中有个rt.jar
rt的意思就是root,核心的包都在这里
双亲委派机制
我创建了一个跟java.lang.String同名的类
package java.lang;
public class String {
public String toString(){
return "hello";
}
public static void main(String[] args) {
String s = new String();
s.toString();
}
}
运行结果:
它说 在类 java.lang.String 中找不到 main 方法,为什么呢?我们可以看到代码中这个路径下的类中有main方法啊,为什么它说没有呢
所以我们可以得出结论,它走的不是上面代码的main方法
双亲委派机制是为了保证安全的
1、App-->Ext-->Boot(最终执行)
它首先会从boot加载器中找,如果找到了java.lang.String它会执行根加载器中的String方法。
如果Boot根加载器中找不到这个类,它会倒着找,从EXT中找,如果EXT中也没有,就会到App用程序加载器中找。
如果在这三个加载器中都找不到你写的类,就会报一个经典的错误:Class Not Found