慢慢来比较快,虚心学技术
前言:在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。
同文链接:https://www.jianshu.com/p/63774338a87d
概念
ClassLoader:类的加载器,用来把类(class)装载进 JVM
java装载类的方式有两种:
①隐式装载:程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中
②显式装载:通过Class.forName()等方式动态显式加载需要的类【如上一篇文章所示】
ClassLoader层级
java的类装载器有如下几种:
①Bootstrp ClassLoader: 引导类装载器,用C++语言编写,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib
,-Xbootclasspath
参数指定的路径以及%JAVA_HOME%/jre/classes
中的类。java中获取时名称为:
②ExtClassLoader:扩展类装载器,负责装载jdk home/lib/ext目录下的jar包
③AppClassLoader :系统类装载器,最常用的类装载器。负责装载classpath路径下的类文件
三种类装载器的有层级关系,层级关系如下:
Bootstrp ClassLoader是ExtClassLoader的父级类装载器
ExtClassLoader是AppClassLoader的父级类装载器
主要方法
ClassLoader.getSystemClassLoader()---------获取系统类加载器
classLoader.getParent()-----------获取加载器的父级类加载器
class.getClassLoader()------------获取当前类的加载器
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("systemClassLoader :"+systemClassLoader);
//获取扩展类加载器
ClassLoader extentionClassLoader = systemClassLoader.getParent();
System.out.println("extentionClassLoader :"+extentionClassLoader);
//试图获取引导类加载器(无法获取)
ClassLoader bootstapClassLoader = extentionClassLoader.getParent();
System.out.println("bootstapClassLoader :"+bootstapClassLoader);
//测试当前类由哪个类加载器进行加载(系统类加载器):
BaseEntity baseEntity = new BaseEntity();
ClassLoader classLoader = baseEntity.getClass().getClassLoader();
System.out.println("程序内定义的类由:"+classLoader+" 进行加载");
classLoader = Integer.class.getClassLoader();
//如果为空则代表是引导类,无法获取
System.out.println("系统Integer由:"+classLoader+" 进行加载");
运行结果:
systemClassLoader :sun.misc.Launcher$AppClassLoader@18b4aac2
extentionClassLoader :sun.misc.Launcher$ExtClassLoader@2503dbd3
bootstapClassLoader :null
程序内定义的类由:sun.misc.Launcher$AppClassLoader@18b4aac2 进行加载
系统Integer由:null 进行加载
注: 由于Bootstrp ClassLoader是由c++编写的,所以无法通过代码获取!!!
双亲委派机制
那么,当一个类需要加载的时候,ClassLoader到底是如何工作的呢?这里涉及到ClassLoader的双亲委派机制
双亲委派机制 某个特定的类加载器在接到加载类的请求时,首先将加载任务委托交给父类加载器,父类加载器又将加载任务向上委托,直到最父类加载器,如果最父类加载器可以完成类加载任务,就成功返回,如果不行就向下传递委托任务,由其子类加载器进行加载。 双亲委派机制的好处: 保证java核心库的安全性(例如:如果用户自己写了一个java.lang.String类就会因为双亲委派机制不能被加载,不会破坏原生的String类的加载)
总结
1.ClassLoader是用来将类装载入JVM的类加载器,java程序类加载有隐式和显式(动态)两种
2.ClassLoader主要包括引导类装载器(Bootstrp ClassLoader),扩展类装载器(ExtClassLoader),系统类装载器(AppClassLoader )三种,三种类加载器存在层级关系,各司其职
3.由于Bootstrp ClassLoader是由c++编写的,所以无法通过代码获取
4.双亲委派机制可以保护java核心库的安全性,也提高了程序性能
参考文档
【1】https://www.cnblogs.com/tech-bird/p/3525336.html
【2】https://www.cnblogs.com/doit8791/p/5820037.html
【3】《java编程思想》