1.反射概念
反射是在运行状态中,对于任意一个类,都能够知道这个类所有的方法和属性,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取信息的功能称为反射机制。
2.反射的作用及功能
前提: 运行时!!!!!
1.判断任意一个对象所属的类
2.构造任意一个类的对象
3.判断任意一个类的所具有的属性和方法
4.调用任意一个对象的方法
3.什么是动态性?
动态性: 指在运行时代码可以根据某些条件改变自身结构,java不是动态语言,但可以利用反射机制来实现。
静态性:编译器进行编译后代码成为硬码无法改变
4.反射的加载原理
程序经过javac.java命令以后,会生成一个或多个class字节码文件,接着我们使用java.exe命令对某个字节码文件进行解释运行,JVM使用类加载器会将这个文件加载并创建一个对应的Class实例到内存中,这个过程称为类加载,在内存中的类称为运行时类,而这个类就是Class实例。Class类的实例就表示这个文件,该实例包含了完整的类结构信息,这个对象就像一面镜子将类的结构展示给我们,所以称为反射。
5.使用反射的基本步骤
1.导入java.lang.reflect.
2.获取操作类的java.lang.Class对象
3.调用Class的方法获取Field、Method等对象
4.使用反射API操作实例成员
6.获取Class对象的三种常用方式
一般使用第二种方式: 第一种不简洁,第三种要处理异常.
//1.对象.getClass()
Student student=new Student();
Class clazz = student.getClass();
//2.类.class
Class clazz1=Student.class;
//3.Class.forName()
try {
Class clazz2 = Class.forName("xxx.xxx.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
7.JVM提供的Class实例方法
Class实例方法可以获取类的构造器、方法、属性、类信息,由JVM虚拟机提供了64种方法,大部分摘要如下图:
该图片来源: (15条消息) Java基础之—反射(非常重要)_敬业小码哥的博客-CSDN博客_java反射
8.利用反射实例化的两种方式
8.1 class实例.newInstance()
Class<Student> studentClass = Student.class; //获取class实例
Student student = studentClass.newInstance(); //根据实例调用构造器
注意:这种方式JDK9版本以后是过期的
8.2 通过构造器来创建
//获取构造器信息
Constructor<Student> declaredConstructor = studentClass.getDeclaredConstructor();
//根据构造器信息创建实例
Student student = declaredConstructor.newInstance();
9.使用Filed对实例中的属性进行取值和赋值操作
9.1赋值
setAccessible(true)用于检查java语言访问权限,如果获取的属性或方法为私有的,那么可以设置此方法关闭权限,对数据进行操作。
Class<Student> studentClass = Student.class; //获取Class对象
Field age = studentClass.getDeclaredField("age");
age.setAccessible(true) //禁止java语言访问检查
age.set(student,40); //对象,参数
9.2 取值
age.get(student);
10.使用Method对实例中的方法进行操作
//获取Class对象
Class<Student> studentClass = Student.class;
//获取构造器信息
Constructor<Student> declaredConstructor = studentClass.getDeclaredConstructor();
//根据构造器信息创建实例
Student student = declaredConstructor.newInstance();
//获取方法信息
Method print = studentClass.getDeclaredMethod("print", int.class);
//关闭java语言检查
print.setAccessible(true);
//调用方法:第一个参数为所创建的实例,第二个为方法的参数值
print.invoke(student,2);