定义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
例如:一个类有:成员变量、方法、构造方法等等信息,利用反射技术可以对一个类进行拆分,组成部分映射成一个个对象。
回顾Class对象生成
类加载进JVM的时候,三个步骤:
- 通过全限定类名获取该类的二进制的字节流
- 将静态的存储结构变成方法区运行时的数据结构
- 生成java.lang.Class对象,作为方法区这个类的各种数据结构访问入口
反射的使用
Class类
- 根据类名:类名.class
- 根据对象:对象.getClass()
- 根据全限定类名:Class.forName(全限定类名)
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//类名.class
Class<String> stringClass = String.class;
//对象.getClass()
String str = "abc";
Class<? extends String> aClass = str.getClass();
//全限定类名
Class<?> clazz = Class.forName("java.lang.String");
//实例化类
Object o = clazz.newInstance();
}
Constructor类
Constructor类存在于反射包(java.lang.reflect)中,反映的是Class 对象所表示的类的构造方法。
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.juejin.Student");
//默认构造方法 Student必须包含无参构造
Student student = (Student) clazz.newInstance();
student.setAge(18);
student.setName("弥金");
//指定参数类型构造方法
Constructor<?> constructor = clazz.getConstructor(int.class, String.class);
//private必须设置为可访问
constructor.setAccessible(true);
constructor.newInstance(18, "弥金");
//获取所有构造方法
Annotation[] declaredAnnotations = clazz.getDeclaredAnnotations();
}
Field类
Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.juejin.Student");
//public修饰符(注意字段必须存在)
Field field = clazz.getField("name");
//任意修饰符(注意字段必须存在)
Field declaredField = clazz.getDeclaredField("age");
//获取所有字段(包括私有的)
Field[] declaredFields = clazz.getDeclaredFields();
//获取所有字段(仅public)
Field[] fields = clazz.getFields();
//浅浅赋值一下
Student student = (Student) clazz.newInstance();
declaredField.setAccessible(true);
declaredField.set(student, 18);
}
Method类
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息,所反映的方法可能是类方法或实例方法(包括抽象方法)。
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.juejin.Student");
Student student = (Student) clazz.newInstance();
student.setAge(18);
//获取所有public的方法
Method[] methods = clazz.getMethods();
//获取当前类的方法(包含private),无法获取继承自父类的方法哦
Method[] declaredMethods = clazz.getDeclaredMethods();
//获取具体的方法
Method getAge = clazz.getDeclaredMethod("getAge");
//浅浅地调用一下
getAge.setAccessible(true);
Object invoke = getAge.invoke(student);
System.out.println(invoke);
}