class类文件只有经过类加载器加载后才能new出实例对象,所以不一样类加载器中的对象和类都是不一样的(即便类文件相同)。java
java中的类加载器主要包括引导类加载器、扩展类加载器、系统类加载器以及自定义类加载器,而且各个类加载器之间按照树状层级(也称双亲委派)进行组合。引导类加载器负责加载lib目录中的类库而且该类加载器不能被java程序直接引用;扩展类加载器负责加载ext目录中类库但可被java程序直接引用,全部能被java程序直接引用的类加载器都继承于CLassLoader抽象类;系统类加载器负责加载由classpath指定的类库;自定义类加载器负责加载由用户指定路径的类库。spa
各个类加载器之间(除了引导类加载器)采用组合模式进行设计,因此通常在自定义类加载器时都须要指定一个父类加载器。这样设计的好处是避免同一类库的重复加载从而节约资源,而且当加载某个类文件时若是父加载器已经加载过就不会重复加载相同的类文件(类文件经过包名和类名进行惟一标识,若是不这样作,当用户写了一个java.lang.String类,就会使得已经写好的程序发生错乱,而且用户能够随机写一个与系统类相同的类文件进行恶意破坏)。设计
如下代码可对上述进行验证:对象
public class ClassLoaderTest {继承
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(ClassLoaderTest.class.getClassLoader()); //1
System.out.println(ClassLoader.getSystemClassLoader()); //2
System.out.println(ClassLoaderTest.class.getClassLoader().getParent()); //3
System.out.println(ClassLoaderTest.class.getClassLoader().getParent().getParent()); //4
}资源
}get
第1行和第2行表明系统类加载器,第3行表明扩展类加载器也是系统类加载器的父加载器,第4行是咱们试图获取扩展类加载器的父加载器即引导类加载器可是返回的结果为空(印证了引导类加载器不能直接被java程序引用)。class