反射
Java语言是一门静态化语言,反射赋予它动态化,让Java拥有动态化语言的一些特点
Java反射指的是程序在运行期间,可以动态性的获取类的内部组成(类、属性、方法、构造方法、接口、父类)
反射是高级编程、可以破坏Java的封装、但不能滥用反射、反射的效率相对不高
反射通常多应用于框架
类加载
JVM 第一次读取一个类的时候、将类的字节码.class 读取到内存的过程,被称为类加载
类加载的产物是 类对象(字节码对象),用 Class 来表示
双亲委派机制
在 java中 , 加载一个类、需要 使用 ClassLoader 进行加载
- BootstrapClassLoader (启动类加载器)
加载JDK官方自带的核心类
- ExtClassLoader (扩展类加载器)
加载JDK官方自带的扩展类
-
AppClassLoader (应用类加载器)
-
加载 classpath 类路径下的类
作用
防止 JDK 核心类被篡改
保证一个类只会被加载一次
Tomcat Web服务器 打破了双亲委托机制
一个 tomcat服务器下可以部署多个项目,但是每一个应用可能会用到不能版本的JAR
具体内容可以详见百度
类对象
- Class<类型> clazz = 类型.class ;
- Class<? extends 类型> clazz = obj.class ;
- Class<?> clazz = Class.forName(“类全名”)
获取一个类的父类
- getSuperclass() : 获取一个类的直接父类、如果一个类没有继承,则返回 Object的类对象,如果是Object, 则返回null
- getGenericSuperclass() : 获取一个类的直接父类(包含泛型信息)、返回一个 Type类型,实质上是ParameterizedType
获取一个类实现的接口
- getInterfaces() : 获取一个类实现的直接接口,返回一个Class数组
- getGenericInterfaces() : 获取一个类实现的直接接口(包含泛型信息), 返回一个Type数组
获取构造方法 Constructor
- getDeclaredConstructors() : 获取类中所有的构造方法
- getDeclaredConstructor(Class<?>… parameterType) : 获取类中指定的构造方法
- getConstructors() : 获取类中所有 public 修饰的构造方法
- getConstructor(Class<?>… parameterType) : 获取类中指定的公开的构造方法
Constructor 中常见的方法
-
setAccessible(flag) : 是否允许访问 ,如果设置为true, 则权限修饰符会被直接绕过
-
newInstance(Object…) : 创建对象
-
getName() : 获取构造方法的全名 (包名 + 类名)
-
getModifiers() : 获取构造方法的修饰符,返回int,可以配置 Modifier类中提供的方法和属性进行判断
-
getParameterCount() : 获取构造方法的参数个数
-
getParameterTypes() : 获取构造方法的参数列表、返回一个 Class 数组
-
isAnnotationPresent(Class clz) : 判断 构造方法上是否包含某个注解
-
getAnnotation(Class clz) : 获取构造方法上指定的注解
获取类中的属性 Field
- getDeclaredFields() : 获取类中定义的所有属性(本类中定义、不包含父类)
- getDeclaredField(String name) : 根据属性的名字 获取 属性
- getFields() : 获取公开的属性(包含继承父类的公开属性)
- getField(String name) : 根据属性的名字,获取公开的属性
Field 中常见的方法
- getName() : 获取属性名
- getType() : 获取属性类型,返回Class
- getModifiers() : 获取修饰符
- get(obj) : 获取指定对象的 属性值
- set(obj, val) : 给指定对象的属性设置值
- getXxx(obj): 获取obj对象的属性值,值是基本数据类型
- setXxx(obj, val)
- setAccessible(flag) :是否允许访问属性
- isAnnotationPresent(Class clz) : 判断 构造方法上是否包含某个注解
- getAnnotation(Class clz) : 获取构造方法上指定的注解
在ClassUtils工具类、添加一个方法 getInterfaces(Class clz) 获取类的所有接口
在ClassUtils工具类、添加一个方法 getFields(Class clz) 获取类的所有属性(包含父类)
获取类中的方法 Method
- getDeclaredMethods() : 获取当前类中定义的所有方法
- getDeclaredMethod(String method, Class<?> parameterType) : 根据方法名、参数列表获取对应的 Method
- getMethods() : 获取 类中所有的 公开方法(包括父类中的公开方法)
- getMethod(String method, Class<?> parameterType) : 获取类中指定的公开方法(包括父类中的公开方法)
Method 中常见的方法
-
getModifiers() : 获取修饰符
-
getReturnType() : 获取方法的返回值类型
-
getName() : 获取方法名
-
getParameterTypes() : 获取方法的参数列表,返回 Class<?>[]
-
getParameterCount() : 获取方法的参数个数
-
setAccessible(flag) :是否允许访问属性
-
invoke(obj, Object…param) : 调用方法
-
isAnnotationPresent(Class clz) : 判断 构造方法上是否包含某个注解
-
getAnnotation(Class clz) : 获取构造方法上指定的注解
当使用 invoke 调用方法的时候,如果方法返回void ,可以用Object 来接收,但值一定是 null
当 Method 是一个静态方法的时候,调用的时候, invoke的第一个参数传入 null 即可
注解 Annotation
注解是可以在编译阶段进行工作 或者 在运行阶段进行工作的,是一个比注释更强大的技术
编译注解: 该注解主要作用于编译阶段,例如 @override,@FunctionalInterface(编译检查),
lombok中提供的注解,用来生成相关的字节码文件
运行注解: 在运行阶段可以具备强大的功能
元注解
给自定义注解添加注解功能的注解
-
@Target : 定义注解使用的位置
- value() : 用来设置注解出现的位置,必传,值可以使用 ElementType
- ElementType.TYPE : 标记注解可以写在类上
- ElementType.FIELD : 标记注解可以写在属性上
- ElementType.METHOD : 标记注解可以写在方法上
- ElementType.CONSTRUCTOR : 标记注解可以写在构造方法上
- ElementType.PARAMETER : 标记注解可以写在方法的参数上
- value() : 用来设置注解出现的位置,必传,值可以使用 ElementType
-
@Retention : 定义注解的作用范围
- value() : 用来设置注解的作用范围,必传,值可以使用 RetentionPolicy
- RetentionPolicy.SOURCE : 可以将注解保留在源码中
- RetentionPolicy.CLASS : 可以将注解保留在字节码中
- RetentionPolicy.RUNTIME : 可以将注解保留在运行时(常用)
- value() : 用来设置注解的作用范围,必传,值可以使用 RetentionPolicy
-
@Documented : 注解是否在生成的javadoc中出现
-
@Inherited : 标记注解是否允许被继承
-
@Repeatable: 标记注解是否允许使用多次,需要配置 其他(复数)注解来实现具体的效果
自定义注解
注解是一个特殊的类、使用 @interface 修饰
注解种可以定义成员,语法格式: 类型 成员名()
注解成员可以使用 default 设置 默认值
注解成员 支持的类型有 字符串、8种基本数据类型、枚举、Class、注解、以及它们对应的数组