反射
作用:
- 对于任意一个对象,把对象所有的字段名和值,保存到文件中去
- 利用反射动态的创造对象和运行方法
1. 获取字节码文件对象
方法 |
描述 |
Class.forName(String) |
通过类的全限定名字符串获取字节码文件对象。 |
类字面量 |
直接使用类的字面量获取字节码文件对象。 |
对象的方式 |
当已经有类的对象时,通过对象的 getClass() 方法获取字节码文件对象。 |
java
复制代码
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) |
设置私有构造方法可访问。 |
java
复制代码
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 {
// 1. 获取Class字节码文件对象
Class clazz = Class.forName("Student");
// 2. 获取所有的构造方法
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);
}
}
java
复制代码
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 表示的字段设置为指定的新值。 |
java
复制代码
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);
}
}
java
复制代码
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) |
返回单个成员方法对象,存在就能拿到 |
java
复制代码
import java.lang.reflect.Method;
public class ReflectMethodExample {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
// 获取Class对象
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.");
}
}