Java反射机制:是指在运行的时候去获取一个类变量和类方法的信息。然后通过获取到的信息来创建对象,
调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展
一、获取Class类型对象的三种方式:
1.知道类名情况下,使用类的clss属性来获取该类对应的Class对象
eg:Student.class将会返回Student类对应的Class对象
2.知道对象名情况下,调用对象的getClass()方法,返回该对象对应的Class对象
该方法是Object类中的方法,所有的Java对象都可以调用该方法
3.知道类的包名和类名情况下,使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整的包名的路径
Class.forName(“包名+类名”);
二、通过Class对象获取构造方法:
getConstructors():获取所有的公共的构造方法,返回一个构造方法数组
getDeclaredConstructors():获取所有的构造方法,包括私有;返回一个构造方法数组
getConstructor(Class<?>… parameterTypes):获取单个公共的构造方法
getDeclaredConstructor((Class<?>… parameterTypes):返回单个构造方法对象
用于创建对象的方法: T newInstance(Object…initargs):根据指定的构造方法创建对象
- 使用反射创建一个对象:
1.获取Class对象
2.通过Class对象获取构造方法对象
3.通过构造方法对象调用newInstance()方法创建一个对象 - 基本数据类型也是可以通过 .class 得到对应的Class类型
- 暴力反射:setAccessible(boolean flag):值为true,取消访问检查,可以使用私有构造方法创建对象
三、获取成员变量:
1.getFields(): 获取所有公共的成员变量,返回一个数组
2.getDeclaredFields(): 返回所有成员变量对象的数组
3.getField(String name): 返回单个公共成员变量对象
4.getDeclaredField(String name): 返回单个成员变量对象
- 给成员变量赋值:
1.获取class对象
Class studentClass = Student.class;
2.成员变量依赖于对象存在,通过newInstance()创建对象
Constructor stu = studentClass.getDeclaredConstructor();
Student student = stu.newInstance();
3.通过class对象获取成员变量
Field field = studentClass.getDeclaredField(“name”);
4.filed.setAccessible(true): 取消访问检查
field.setAccessible(true);
5.赋值field.set(对象名(Object),值(value)):给对象Object赋值为value
field.set(student,“张三”);
四、获取成员方法:
1.getMethods(): 获取所有公共成员方法,包括继承的方法
2.getDeclaredMethods(): 本类的所有方法,不包含继承的
3.getMethod(String name, Class<?>… parameterTypes): 获取单个公共成员方法
4.getDeclaredMethod(String name, Class<?>… parameterTypes): 获取单个成员方法
调用方法的执行的方法:invoke(Object obj,Object… args)调用obj对象的成员方法,参数是args,返回值是Object类型
步骤:
1.获取class对象
Class studentClass = Student.class;
2.获取成员方法
Method show = studentClass.getDeclaredMethod(“show”);
3.对象才能调用成员方法,创建对象
Constructor stu = studentClass.getDeclaredConstructor();
Student student = stu.newInstance();
4.调用方法:
show.setAccessible(true);
show.invoke(student);
//调用静态方法: show.invoke(null);
五、反射可以越过泛型检查
1.往Integer类型集合中添加字符串
ArrayList list = new ArrayList<>();
list.add(10);
list.add(20);
2.获取集合的字节码文件
Class<? extends ArrayList> listClass = list.getClass();
3.获取list集合的添加方法
Method method = listClass.getDeclaredMethod(“add”, Object.class);
4.向集合中添加字符串数据
method.invoke(list,“张三”);
method.invoke(list,“李四”);
5.打印输出
System.out.println(list);