Java 反射(Reflection)是一种在运行时分析和操作 Java 程序的能力,可以动态地获取类的结构信息、调用方法、访问字段等。
reflect
反射是由 java.lang.reflect 包支持的,主要类包括 Class、Method、Field 和 Constructor 等。
示例类
public class Student {
// 属性
private String name;
private int age;
public static String school = "High School";
// 构造方法
public Student() {
this.name = "Unknown";
this.age = 0;
}
private Student(String name) {
this.name = name;
this.age = 18; // 默认年龄
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 公有方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void introduce() {
System.out.println("Hi, my name is " + name + ", and I am " + age + " years old.");
}
// 私有方法
private void printSecret() {
System.out.println("This is a private method.");
}
// 静态方法
public static String getSchool() {
return school;
}
public static void setSchool(String schoolName) {
school = schoolName;
}
}
获取Class对象
- 通过对象获取
Class<?> clazz = object.getClass();
public static void main(String[] args) { Student stu = new Student("Bileton",21); Class stuClass = stu.getClass(); System.out.println(stuClass.getName()); // Student }
- 通过类获取
Class<?> clazz = ClassName.class;
public static void main(String[] args) { Class stuClass = Student.class; System.out.println(stuClass.getName()); // Student }
- 通过全类名获取类
Class<?> clazz = Class.forName("com.example.SomeClass");
public static void main(String[] args) throws ClassNotFoundException { Class strClass = Class.forName("java.lang.String"); System.out.println(strClass.getName()); // java.lang.String }
获取构造方法
- 获取公有构造方法对象的数组
Constructor<?>[] getConstructors()
public static void main(String[] args) { Class stuClass = Student.class; Constructor[] constructors = stuClass.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } }
- 获取所有构造方法对象的数组
Constructor<?>[] getDeclaredConstructors()
public static void main(String[] args) { Class stuClass = Student.class; Constructor[] constructors = stuClass.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } }
- 获取单个公有构造方法对象
Constructor<?> getConstructor()
public static void main(String[] args) throws NoSuchMethodException { Class stuClass = Student.class; Constructor constructor1 = stuClass.getConstructor(); Constructor constructor2 = stuClass.getConstructor(String.class,int.class); System.out.println(constructor1); System.out.println(constructor2); }
- 获取单个构造方法对象
public static void main(String[] args) throws NoSuchMethodException { Class stuClass = Student.class; Constructor constructor = stuClass.getDeclaredConstructor(String.class); System.out.println(constructor); }
- 调用公有构造方法
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Class stuClass = Student.class; Constructor constructor = stuClass.getConstructor(String.class,int.class); Student stu = (Student) constructor.newInstance("Bileton",21); System.out.println(stu.getName()+" "+stu.getAge()); // Bileton 21 }
- 调用私有构造方法
使用setAccessible(true)
突破 Java 的访问控制限制,使得私有成员(字段、方法或构造方法)可以被访问。public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Class stuClass = Student.class; Constructor constructor = stuClass.getDeclaredConstructor(String.class); constructor.setAccessible(true); Student stu = (Student) constructor.newInstance("Bileton"); System.out.println(stu.getName()+" "+stu.getAge()); // Bileton 18 }
获取成员变量
-
获取公有成员变量对象的数组
Field[] getFields()
public static void main(String[] args) { Class stuClass = Student.class; Field[] fields = stuClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); // school } }
-
获取所有成员变量对象的数组
Field[] getDeclaredFields()
public static void main(String[] args) { Class stuClass = Student.class; Field[] fields = stuClass.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } }
-
获取单个公有成员变量对象
Field[] getField(String name)
public static void main(String[] args) throws NoSuchFieldException { Class stuClass = Student.class; Field fields = stuClass.getField("school"); System.out.println(fields); // public static java.lang.String Student.school }
-
获取单个成员变量对象
Field[] getDeclaredField(String name)
public static void main(String[] args) throws NoSuchFieldException { Class stuClass = Student.class; Field fields = stuClass.getDeclaredField("name"); System.out.println(fields); // private java.lang.String Student.name }
获取和访问字段
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
Class stuClass = Student.class;
Constructor constructor = stuClass.getConstructor(String.class,int.class);
Student Stu = (Student) constructor.newInstance("Bileton",21);
Field name_field = stuClass.getDeclaredField("name");
Field age_field = stuClass.getDeclaredField("age");
name_field.setAccessible(true);
age_field.setAccessible(true);
String name = (String) name_field.get(Stu);
int age = (int) age_field.get(Stu);
System.out.println(name+" "+age); // Bileton 21
name_field.set(Stu,"bileton");
age_field.set(Stu,18);
name = (String) name_field.get(Stu);
age = (int) age_field.get(Stu);
System.out.println(name+" "+age); // bileton 18
}
获取成员方法
-
获取公有成员方法对象的数组,包括继承的
Method[] getMethods()
public static void main(String[] args) throws NoSuchFieldException { Class stuClass = Student.class; Method[] methods = stuClass.getMethods(); for (Method method : methods) { System.out.println(method); } }
-
获取所有成员方法对象的数组,不包括继承的
Method[] getDeclaredMethods()
public static void main(String[] args) throws NoSuchFieldException { Class stuClass = Student.class; Method[] methods = stuClass.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } }
-
获取单个公有成员方法对象
Method getMethod(String name,Class<?>…parameterTypes)
public static void main(String[] args) throws NoSuchMethodException { Class stuClass = Student.class; Method method = stuClass.getMethod("introduce"); System.out.println(method); }
-
获取单个成员方法对象
Method getDeclaredMethod(String name,Class<?>…parameterTypes)
public static void main(String[] args) throws NoSuchMethodException { Class stuClass = Student.class; Method method = stuClass.getDeclaredMethod("printSecret"); System.out.println(method); }
调用成员方法
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
Class stuClass = Student.class;
Constructor constructor = stuClass.getConstructor(String.class,int.class);
Student Stu = (Student) constructor.newInstance("Bileton",21);
Method printSecret = stuClass.getDeclaredMethod("printSecret");
printSecret.setAccessible(true);
printSecret.invoke(Stu); // This is a private method.
}
其他方法
-
getModifiers()
获取成员(类、方法、构造器或字段)的修饰符。 -
getParameters()
获取方法的参数信息。
这个方法返回一个 Parameter[] 数组,每个 Parameter 对象代表方法的一个参数。 -
setAccessible(true)
临时取消权限校验 -
getName()
获取各种对象的名称 -
getType()
获取字段或参数的类型 -
get()
获取字段的值 -
set()
修改字段的值 -
invoke()
调用方法