问题
写测试,自定义String类,代码如下:
package java.lang;
/**
* Created By zby on 23:03 2019/11/12
* 自定义<code>String</code>类
*/
public class String {
public static void main(String[] args) {
new String();
}
}
你仔细看报错的信息,你会感觉很疑惑,我明明在我自定义的String中写了main方法,为什么还是会报错呢?这就涉及到了双亲委派模式。
双亲委派
类加载器
再说双亲委派时,我们就得不说类加载器。类加载器并不神秘,只是我们觉着神秘了。
当JVM将Java源代码转化为字节码时,类加载器就加载和初始化字节码文件。至于它能不能运行,以及运行效果,类加载器就不关注了,这由execution engine来做的。
类加载器普遍分为以下几种类型:
扩展类加载器(Extension Class Loader),这是由Java来写的,加载的是Javahome/jre/lib/ext/*.jar.
应用类加载器(APPClassLoder),这是加载classPath下面的类。
我么通过以下代码来看这几个类加载器:
public class ClassLoaderCheck {
public static void main(String[] args) {
System.out.println(ClassLoaderCheck.class.getClassLoader().getParent().getParent());
System.out.println(ClassLoaderCheck.class.getClassLoader().getParent());
System.out.println(ClassLoaderCheck.class.getClassLoader());
System.out.println("=================");
System.out.println(Object.class.getClassLoader());
}
}
双亲委派
我们自定义的类通过类加载器实例化对象时,类加载器会向上查找父类加载器所在的类对象。如果我们自定义中的类与父类加载器所加载的类对象一致,如果当前类对象没有我们定义的某个方法,其会报错,正如上面的string报的错。
如果任何一个父类加载器都加载不了我们自定义的类,那么,才是用appClassLoder类加载器,加载我们自定义的类。
这就是双亲委派模式,即委派给父类加载器。这样就不允许用户串改jdk的源码,也保证了代码的安全。