企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 第四章第一节--反射 标签(空格分隔): 廖雪峰 --- ## class类 Java除了基本数据类型之外其他都是class(包括interface) - String - Object - Runnable - Execption - ... class/interface的数据类型是Class(注意这里区分大小写) 每加载一个class,JVM就会为其创建一个Class类型的实例,并关联起来. 当JVM加载String类的时候,先读取String.class文件,再为String创建一个Class实例 `Class cls = new Class(String);(仅用来演示过程,Class为private,自己代码是无法创建的)` JVM持有的每一个Class实例都指向一个数据类型(class或者interface) ![Class实例对比](http://p0b921qfc.bkt.clouddn.com/18-5-17/5715564.jpg) 一个Class实例包含了该class的完整信息. ![Class的完整信息](http://p0b921qfc.bkt.clouddn.com/18-5-17/47214925.jpg) **所以说:** 1. JVM为每个加载的class创建对应的Class实例,并在实例中保存该class的所有信息. 2. 如果获取了某个Class实例,则可以获取到该实例对应的class的所有信息. 3. 通过Class实例获取class信息的方法就叫做**反射**. 如何获取一个class的Class实例呢? 1. Type.class `String.class` 2. getClass() `String s = "hello"; Class cls = s.getClass();` 3. Class.forName() `Class cls = Class.forName("java.lang.String");` ![三种调用方式](http://p0b921qfc.bkt.clouddn.com/18-5-17/46471517.jpg) 注意: Class实例在JVM中是唯一的 可以用`==`比较两个Class的实例. ![三种方式比较相同](http://p0b921qfc.bkt.clouddn.com/18-5-17/21165063.jpg) - Class实例和instanceof的差别.(用的比较多) - `==`只能做精确类型的对比,不能做子类的判断. - instanceof:不但匹配当前类型,还匹配当前类型的子类型. ![对比结果](http://p0b921qfc.bkt.clouddn.com/18-5-17/12148084.jpg) ## 反射 反射的目的:当获取某个Object实例时,我们可以获取该Object的class的所有信息. 从Class实例中获取class信息: - getName() 获取类名 - getSimpleName() 获取简写类型 - getPackage() 包名. ![Class中获取的基本信息](http://p0b921qfc.bkt.clouddn.com/18-5-17/83464025.jpg) 从Class实例判断class的类型. - isInterface() 是不是接口 - isEnum() 是不是枚举类型. - isArray() 是不是数据类型. - isPrimitive() 是不是基本数据类型. ![判断信息](http://p0b921qfc.bkt.clouddn.com/18-5-17/46533131.jpg) 创建classs实例(自控制) 只能调用其public 没有参数的构造方法. - newInstance() ![新建实例](http://p0b921qfc.bkt.clouddn.com/18-5-17/94670669.jpg) JVM的动态加载 利用其动态加载的特征可以在运行时候加载不同的实现类. ![动态加载的时候判断](http://p0b921qfc.bkt.clouddn.com/18-5-17/95550557.jpg) ## 小节小结 - JVM为每一个加载的class创建对应的Class实例来保存class的所有信息. - 获取一个clas对应的Class之后,就可以获取class的所有信息. - 通过Class实例去获取class信息的方法就叫做反色(Reflection) - JVM总是动态加载class的,可以在运行的时候根据条件判断加载class.