反射
1. 反射介绍
反射:是指程序在运行期间,动态的获取某个类的信息(属性、方法、构造方法),并且访问
万物皆对象:类也是对象,方法也是对象,构造方法也是对象,属性也是对象Class java.lang.Class Class类中提供了获取当前类对象中编写的属性、方法、构造方法的方法
Constructor java.lang.reflect.Constructor 所有的构造器都属于此类型
Method java.lang.reflect.Method 所有的方法都属于此类型
Field java.lang.reflect.Field 所有的字段都属于此类型
注意:获取的公开的包括父类 获取所有定义的不包括父类
Class 对象的三种创建方式:
- 类名.class
- 对象名.getClass()
- Class.forName(“全称类名”)
方法名 | 说明 | |
---|---|---|
构造器 | getConstructors() | 获取所有的public修饰的构造器,由于构造器无法继承所以不包含父类,返回值为数组 |
getDeclaredConstructors() | 获取本类中所有已定义的构造器,不包含父类,返回值为数组 | |
getConstructor() | 获取单个构造器,可传参,参数形式为: 数据类型.class | |
getDeclaredConstructor() | ||
方法 | getMethods() | 获取所有的public修饰的方法,包含父类,返回值为数组 |
getDeclaredMethods() | 获取本类中所有已定义的方法,不包含父类,返回值为数组 | |
getMethod(“方法名”,参数) | 获取具体某个方法,可传参,参数形式为: 数据类型.class | |
getDeclaredMethod() | ||
属性 | getFields | 获取所有的public修饰的属性,包含父类,返回值为数组 |
getDeclaredFields() | 获取本类中所有已定义的属性,不包含父类,返回值为数组 | |
getField(“属性名”) | 获取具体某个属性值,可传参,参数为:属性名 | |
getDeclaredField() |
2. 获取构造器
2.1 获取公开的
通过反射获取public修饰的构造器
会使用到Class类中两个方法
1.getConstructors() 获取所有的public修饰的构造器
2.getConstructor(Class…parameterType)根据形参列表的类型获取一个单独的public修饰的构造器
获取构造器 需要先获取到当前类所属的Class类型对象
2.2 获取非公开的
Class类提供两个方法可以用于获取所有的已定义的构造器 任何访问修饰符修饰的
1.getDeclaredConstructors() 获取所有的已定义的构造器 返回值为构造器数组
2.getDeclaredConstructor(Class<?>…parameterType) 根据形参列表获取一个已定义的构造器
3. 获取方法
3.1 获取公开的
获取公开的方法
getMethods() 获取所有的public修饰的方法以及继承父类的方法
getMethod(String methodName,Class<?>…parameterType) 根据方法名称和参数列表获取到一个方法对象
3.2 获取非公开的
获取所有已定义的方法对象(不包括继承父类)
getDeclaredMethods() 获取本类中所有已定义的方法 返回值为方法数组
getDeclaredMethod(String methodName,Class<?>…parameterType) 根据方法名称参数列表获取单个方法对象
4. 获取属性
4.1 获取公开的
获取公开的属性
getFields() 获取所有public修饰的属性
getField(String fieldName) 根据名字获取单个字段对象
4.2 获取非公开
获取所有已定义的属性
getDeclaredFields() 获取所有已定义的属性 任何访问修饰符修饰的
getDeclaredField(String fieldName) 根据字段名称获取单个字段对象
5实例
Class<?> clz = Class.forName("com.qfedu.test2.Student");
Constructor<?> cons06=clz.getDeclaredConstructor(int.class);//获取单个已定义的有参构造器
cons06.setAccessible(true);// 传入true 表示忽略JVM安全警告 可以访问(若无安全警告可省略)
Object obj1=cons06.newInstance(12);//使用通过反射获取的有参构造器创建对象,
Field fields04=clz.getDeclaredField("id");//获取本类中已定义的具体属性,不包含父类中的,参数为属性名
fields04.setAccessible(true);
fields04.set(obj1,24);//进行属性的修改
Method methods05=clz.getDeclaredMethod("test1",int.class);//获取类中已定义的所有方法,不包含父类
methods05.setAccessible(true);
methods05.invoke(obj1,10);//调用方法,有参
注解
1. 介绍
注解:用于实现特定的功能或者可以来记录数据
回顾一下我们之前接触过的注解 @Override @SuppressWarnings @Deprecated
发现这些注解可以用来实现不同的功能或者效果 可以加在不同的位置
注解:
注解支持的属性类型:八中基本数据类型、Class、String、枚举 再加上对应的数组类型
注解可以书写的位置:由@Target注解来指定
注解的赋值: 如果注解中只有一个属性且属性名为value,可以直接写值,如果属性类型为数组可以直接使用大括号赋值,如果数组只需要
赋一个值,也可以不需要写大括号
其他的情况都必须写为 属性名 = 属性值
我们可以使用default关键字给属性赋默认值
元注解:是用于修饰注解的注解
@Target 表示规定注解可以添加的位置,如果不写表示此注解可以添加在任何位置
@Retention 表示注解的保留范围(生命周期),默认不写为CLASS
- CLASS:表示在二进制文件中生效
- SOURCE:表示在源代码中生效
- RUNTIME:表示在程序执行过程中生效
@Documented(了解)
@Inherited(了解)
2. 使用反射获取注解信息
此类为数据库连接信息工具类
使用指向为null引用,调用属性或者方法都会出现空指针异常