反射
作用:
- 对于任意一个对象,把对象所有的字段名和值,保存到文件中去
- 利用反射动态的创造对象和运行方法
1. 获取字节码文件对象
方法 | 描述 |
---|
Class.forName(String) | 通过类的全限定名字符串获取字节码文件对象。 |
类字面量 | 直接使用类的字面量获取字节码文件对象。 |
对象的方式 | 当已经有类的对象时,通过对象的 getClass() 方法获取字节码文件对象。 |
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
Class clazz = Class.forName("Student");
System.out.println(clazz);
Class clazz2 = Student.class;
System.out.println(clazz2);
System.out.println(clazz==clazz);
Student s = new Student();
Class clazz3 = s.getClass();
System.out.println(clazz3);
System.out.println(clazz2==clazz3);
}
}
2. 利用反射获得构造方法
方法 | 描述 |
---|
Class.forName(String) | 通过类的全限定名字符串获取字节码文件对象。 |
Class.getConstructors() | 获取公共的构造方法。 |
Class.getDeclaredConstructors() | 获取所有构造方法,包括私有的构造方法。 |
Class.getConstructor(Class...) | 获取指定参数类型的公共构造方法。 |
Class.getDeclaredConstructor(Class...) | 获取指定参数类型的构造方法,包括私有的构造方法。 |
Constructor.getModifiers() | 获取构造方法的修饰符。 |
Constructor.getParameters() | 获取构造方法的参数。 |
Constructor.newInstance(Object...) | 通过构造方法创建类的实例。 |
Constructor.setAccessible(true) | 设置私有构造方法可访问。 |
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz = Class.forName("Student");
Constructor[] cons = clazz.getConstructors();
for (Constructor con: cons) {
System.out.println(con);
}
System.out.println("------------");
Constructor[] cons2 = clazz.getDeclaredConstructors();
for (Constructor con: cons2) {
System.out.println(con);
}
System.out.println("------------");
Constructor con3 = clazz.getConstructor(String.class);
System.out.println(con3);
System.out.println("------------");
Constructor con4 = clazz.getDeclaredConstructor(int.class);
System.out.println(con4);
System.out.println("------------");
Constructor con5 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(con5);
System.out.println("------------");
int modifiers = con5.getModifiers();
System.out.println(modifiers);
Parameter[] parameters = con5.getParameters();
for (Parameter parameter: parameters) {
System.out.println(parameter);
}
con5.setAccessible(true);
Student stu = (Student) con5.newInstance("张三", 23);
System.out.println(stu);
}
}
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name) {
this.name = name;
}
protected Student(int age) {
this.age = age;
}
private 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
3. 利用反射获取成员变量
方法 | 描述 |
---|
Class.getFields() | 获取公共的成员变量。 |
Class.getDeclaredFields() | 获取所有的成员变量,包括私有的成员变量。 |
Class.getField(String) | 获取指定名称的公共成员变量。 |
Class.getDeclaredField(String) | 获取指定名称的成员变量,包括私有的成员变量。 |
Field.getModifiers() | 获取成员变量的权限修饰符。 |
Field.get(Object) | 获取指定对象上此 Field 表示的字段的值。 |
Field.setAccessible(true) | 设置私有成员变量可访问。 |
Field.set(Object, Object) | 将指定对象参数上此 Field 表示的字段设置为指定的新值。 |
import java.lang.reflect.Field;
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Class clazz = Class.forName("Student");
Field[] fields = clazz.getFields();
for (Field field: fields) {
System.out.println(field);
}
System.out.printf("------------\n");
Field[] fields2 = clazz.getDeclaredFields();
for (Field field: fields2) {
System.out.println(field);
}
System.out.printf("------------\n");
Field field3 = clazz.getField("gender");
Field name = clazz.getDeclaredField("name");
System.out.println(field3);
System.out.println(name);
int modifiers = field3.getModifiers();
int modifiers2 = name.getModifiers();
System.out.println(modifiers);
System.out.println(modifiers2);
System.out.println("------------");
Student s = new Student("张三", 23);
name.setAccessible(true);
Object value = name.get(s);
System.out.println(value);
name.set(s, "李四");
System.out.println(s);
}
}
public class Student {
private String name;
private int age;
public String gender;
public Student() {
}
public Student(String name) {
this.name = name;
}
protected Student(int age) {
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
4. 获取成员方法
方法名 | 说明 |
---|
Method[] getMethods() | 返回所有成员方法对象的数组(只能拿public的) |
Method[] getDeclaredMethods() | 返回所有成员方法对象的数组,存在就能拿到 |
Method getMethod(String name, Class<?>… parameterTypes) | 返回单个成员方法对象(只能拿public的) |
Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 返回单个成员方法对象,存在就能拿到 |
import java.lang.reflect.Method;
public class ReflectMethodExample {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class<?> clazz = Class.forName("MyClass");
Method[] methods = clazz.getMethods();
System.out.println("公共成员方法:");
for (Method method : methods) {
System.out.println(method);
}
System.out.println("-------------");
Method[] declaredMethods = clazz.getDeclaredMethods();
System.out.println("所有成员方法:");
for (Method method : declaredMethods) {
System.out.println(method);
}
System.out.println("-------------");
Method publicMethod = clazz.getMethod("publicMethod");
System.out.println("指定的公共成员方法:");
System.out.println(publicMethod);
System.out.println("-------------");
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
System.out.println("指定的成员方法:");
System.out.println(privateMethod);
}
}
class MyClass {
public void publicMethod() {
System.out.println("This is a public method.");
}
private void privateMethod() {
System.out.println("This is a private method.");
}
}
5. 调用成员方法
Object invoke(Object obj, Object... args)
实例
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
Object result = invoke(calculator, 5, 3);
System.out.println("Result of addition: " + result);
}
public static Object invoke(Object obj, Object... args) {
try {
Class<?> clazz = obj.getClass();
java.lang.reflect.Method method = clazz.getMethod("add", int.class, int.class);
return method.invoke(obj, args);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
class Calculator {
public int add(int a, int b) {
return a + b;
}
}