Java-类加载器-双亲委派模型

范例:编写一个简单的反射程序,来观察ClassLoader的存在

package com.ClassLoader;

class Member{}

public class Test {
	public static void main(String[] args) {
		Class<?> cls = Member.class;
		System.out.println(cls.getClassLoader());
		System.out.println(cls.getClassLoader().getParent());
		System.out.println(cls.getClassLoader().getParent().getParent());
	}
}

此时出现了两个类加载器:ExtClassLoader(扩展类加载器)、AppClassLoader(应用程序类加载器)



package com.ClassLoader;

class Member {
	@Override
	public String toString() {
		return "haha";
	}
}

public class Test {
	public static void main(String[] args) throws Exception {
		System.out.println(Member.class.getClassLoader().loadClass("com.ClassLoader.Member").newInstance());
	}
}
运行结果:haha


a) Bootstrap(启动类加载器): 

    由C++实现,属于JVM本身的一部分,无法被Java程序直接引用,

    负责加载<Java_Home>/lib下的所有类库(类库名必须能被JVM识别,识别的依旧是按照文件名)eg:rt.jar(JDK基础类,包含所有java开发必备的类如Object类)

    除了启动类加载器以外的所有类加载器,均由java语言开发能被java程序直接使用

    除了启动类加载器以外,所有类加载器都应有父加载器

b) ExtClassLoader(CLASSPATH):加载第三方程序类库:

    负责加载<Java_Home>/lib/ext目录下的所有类库

c) AppClassLoader(自己写的代码):应用程序类加载器:

    负责加载classpath中指定的类库

    如果程序中没有自定义类加载器,则默认使用AppClassLoader类加载器

d) 自定义类加载器

    用户可以自己决定从哪里加载类(本地磁盘、别的磁盘、网络中加载)


类加载器的双亲委派模型

    四中类加载器的层次关系


双亲委派模型的工作流程

    当一个类加载器收到类加载请求时,它会先把加载请求委托给父类加载器,如果父类加载器反馈无法加载时,它才会尝试加载此类。所以,在程序中自定义的类加载器请求都会最终走到启动类加载器,这就是双亲委派。

意义:保证java程序的稳定运行。 eg:有一个自定义的类java.lang.Object, 通过双亲委派,便不会再执行自定义的Object。

双亲委派模型不是强制要求,只是JDK建议这样加载类,可以破坏双亲委派模型,如:OSGI 热加载。






猜你喜欢

转载自blog.csdn.net/qq_35402412/article/details/80300049