目录
认识反射、获取类
反射(Reflection)
- 反射就是:加载类,并允许以编程的方式剖析类中的各种成分(成员变量、方法、构造器等)
反射可进行的操作
加载类,获取类的字节码:Class对象
获取对象的三种方法
- 反射第一步操作必须得到该类的Class对象
- Class c1 = 类名.class
-
package com.example.Test; public class draft { public static void main(String[] args) { Class c1 = Student.class; // 打印输出全类名,即全限定名 System.out.println(c1.getName()); // 打印输出简类名,即类名 System.out.println(c1.getSimpleName()); } } class Student { };
-
运行结果如下
-
-
- 调用Class提供方法:public static Class forname(String package);
-
package com.example.Test; public class draft { public static void main(String[] args) throws Exception { Class c2 = Class.forName("com.example.Test.Student"); System.out.println(c2.getName()); System.out.println(c2.getSimpleName()); } } class Student { };
-
运行结果如下
-
-
- Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
-
package com.example.Test; public class draft { public static void main(String[] args) throws Exception { Student s = new Student(); Class c = s.getClass(); System.out.println(c.getName()); System.out.println(c.getSimpleName()); } } class Student { };
-
运行结果如下
-
-
获取构造器对象并使用
获取构造器的方法
- 构造器就是构造方法
-
方法名 描述 public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取具有指定参数类型的公共(public修饰)构造器。 public Constructor<?>[] getConstructors() 获取所有公共(public修饰)构造器的数组。 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取具有指定参数类型的构造器,包括私有构造器。 public Constructor<?>[] getDeclaredConstructors() 获取所有构造器的数组,包括私有构造器。
- 只演示一种
- 具体代码如下
-
package com.example.Test; import org.junit.Test; import java.lang.reflect.Constructor; public class draft { @Test public static void main(String[] args) throws Exception { // 1. 反射第一步 获取该类的Class对象 Class c = Student.class; // 2. todo 获取该类的全部构造器 Constructor[] constructors = c.getConstructors(); // 3.遍历数组中的构造器 for (Constructor constructor : constructors) { System.out.println(constructor.getName() + "参数个数为:" + constructor.getParameterCount()); } System.out.println("----------------"); // todo 根据参数类型获取构造器 Constructor constructor1 = c.getConstructor(String.class, Integer.class); System.out.println(constructor1.getName() + "参数个数为:" + constructor1.getParameterCount()); } } class Student { private String name; private Integer age; // todo 无参构造方法 public Student() { } // todo 全参构造方法 public Student(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } };
-
-
运行结果如下
-
- 具体代码如下
获取构造器的作用
- 初始化对象返回
- 构造器提供的方法
-
方法名 描述 public T newInstance(Object... initargs) 使用构造器创建一个新的对象实例。initargs参数是构造器的参数列表,用于传递初始化数据。该方法会调用构造器并返回新创建的对象实例。 public void setAccessible(boolean flag) 设置构造器的可访问性。如果flag为true,则可以访问私有构造器(暴力反射);如果flag为false,则无法访问私有构造器。 - 具体代码如下
-
package com.example.Test; import org.junit.Test; import java.lang.reflect.Constructor; public class draft { @Test public static void main(String[] args) throws Exception { // 1. 反射第一步 获取该类的Class对象 Class c = Student.class; // todo 根据参数类型获取构造器 Constructor constructor1 = c.getConstructor(String.class, Integer.class); System.out.println(constructor1.getName() + "参数个数为:" + constructor1.getParameterCount()); Student s1 = (Student) constructor1.newInstance("hkm", 20); // todo 根据参数调用对应的构造器 System.out.println(s1.toString()); System.out.println("-------------------------------"); Constructor constructor2 = c.getConstructor(); System.out.println(constructor2.getName() + "参数个数为:" + constructor2.getParameterCount()); Student s2 = (Student) constructor2.newInstance(); // todo 根据参数调用对应的构造器 System.out.println(s2.toString()); } } class Student { private String name; private Integer age; // todo 无参构造方法 public Student() { System.out.println("无参构造器执行了~~"); } // todo 全参构造方法 public Student(String name, Integer age) { this.name = name; this.age = age; System.out.println("全参构造器执行了~~~"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } };
-
-
运行结果如下
-
获取成员变量和方法对象并使用
-
获取类的成员变量的方法
- Class提供的从类中获取成员变量的方法
-
方法名 描述 public Field getField(String name) 根据成员变量的名称获取公共的成员变量。只能获取到公共的成员变量,不能获取到私有的成员变量。如果指定名称的成员变量不存在,或者指定名称的成员变量不是公共的,则会抛出NoSuchFieldException异常。 public Field[] getFields() 获取所有公共(public修饰的)的成员变量。返回一个Field对象数组,包含了所有公共的成员变量。 public Field getDeclaredField(String name) 根据成员变量的名称获取指定的成员变量,包括私有的成员变量。如果指定名称的成员变量不存在,或者指定名称的成员变量不是当前类的成员变量,则会抛出NoSuchFieldException异常。 public Field[] getDeclaredFields() 获取所有的成员变量,包括公共的和私有的。返回一个Field对象数组,包含了所有的成员变量。 - 具体代码
-
package com.example.Test; import org.junit.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class draft { @Test public static void main(String[] args) throws Exception { // 1. 反射第一步 获取该类的Class对象 Class c = Student.class; // todo 获取类中的全部成员变量 Field[] fields = c.getDeclaredFields(); for (Field field : fields) { System.out.println(field.getName()); } System.out.println("------------------"); // todo 通过名称获取某个成员变量 Field name = c.getDeclaredField("name"); System.out.println(name.getName()); } } class Student { private String name; private Integer age; // todo 无参构造方法 public Student() { System.out.println("无参构造器执行了~~"); } // todo 全参构造方法 public Student(String name, Integer age) { this.name = name; this.age = age; System.out.println("全参构造器执行了~~~"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } };
-
-
运行结果
-
-
获取类的成员变量的作用
-
赋值、取值
-
赋值取值的方法
-
方法 说明
void set(Object obj,value) 赋值(为指定对象的成员变量赋值) void get(Object obj) 取值(取出指定对象的成员变量的值) public void setAccessiable(boolean flag) 设置为true,表示禁止访问控制(暴力反射
-
-
具体代码如下
-
package com.example.Test; import org.junit.Test; import javax.swing.plaf.synth.SynthUI; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class draft { @Test public static void main(String[] args) throws Exception { // 1. 反射第一步 获取该类的Class对象 Class c = Student.class; // todo 获取类中的全部成员变量 Field[] fields = c.getDeclaredFields(); for (Field field : fields) { System.out.println(field.getName()); } System.out.println("------------------"); // todo 通过名称获取某个成员变量 Field name = c.getDeclaredField("name"); // todo 创建要赋值以及取值的类的对象 Student student = new Student(); name.set(student, "发老爷爷"); System.out.println(student); // 赋值成功 System.out.println(name.get(student)); // todo 上述代码是对指定类Student中的name成员变量进行操作 // todo 以下是对Student类中的age成员变量进行操作 Field age = c.getDeclaredField("age"); // 赋值 age.set(student, 31); System.out.println(student); System.out.println(age.get(student)); System.out.println("Student类中的age成员变量的赋值为"+ age.get(student)); } } class Student { public String name; public Integer age; // todo 无参构造方法 public Student() { System.out.println("无参构造器执行了~~"); } // todo 全参构造方法 public Student(String name, Integer age) { this.name = name; this.age = age; System.out.println("全参构造器执行了~~~"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } };
-
-
运行结果如下
-
-
获取成员方法的方法
-
方法 说明 getDeclaredMethods()
返回类中声明的所有方法,包括公共、保护、默认(包)访问和私有方法。 getMethods()
返回类中所有公共方法,包括从父类继承的方法。 getDeclaredMethod(String name, Class<?>... parameterTypes)
返回类中指定名称和参数类型的方法。 getMethod(String name, Class<?>... parameterTypes)
返回类中指定名称和参数类型的公共方法,包括从父类继承的方法。 - 具体代码如下
-
package com.example.Test; import org.junit.Test; import java.lang.reflect.Method; public class draft { @Test public static void main(String[] args) throws Exception { // 1. 反射第一步 获取该类的Class对象 Class c = Student.class; // todo 获取全部成员方法 Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()); } System.out.println("------------------------------------"); // todo 获取某个成员方法 Method student = c.getDeclaredMethod("run"); System.out.println(student.getName()); } } class Student { public String name; public Integer age; public void run() { System.out.println("run~~~~"); } private void jump() { System.out.println("jump~~~"); } // todo 无参构造方法 public Student() { System.out.println("无参构造器执行了~~"); } // todo 全参构造方法 public Student(String name, Integer age) { this.name = name; this.age = age; System.out.println("全参构造器执行了~~~"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } };
-
- 运行结果如下
获取成员方法的作用
- 依然是执行该方法
-
方法 说明 public Object invoke(Object obj,Object ...args) 触发某个对象的该方法执行 public void setAccessible(boolean flag) 设置为true,表示禁止访问控制(暴力反射) - 具体代码如下
-
package com.example.Test; import org.junit.Test; import java.lang.reflect.Method; public class draft { @Test public static void main(String[] args) throws Exception { // 1. 反射第一步 获取该类的Class对象 Class c = Student.class; // todo 获取全部成员方法 Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()); } System.out.println("------------------------------------"); // todo 获取某个成员方法 Method run = c.getDeclaredMethod("run"); Method jump = c.getDeclaredMethod("jump", String.class); jump.setAccessible(true); Student student = new Student(); jump.invoke(student, "hkm"); run.invoke(student); } } class Student { public String name; public Integer age; public void run() { System.out.println("run~~~~"); } private void jump(String name) { System.out.println(name + ":jump~~~"); } // todo 无参构造方法 public Student() { System.out.println("无参构造器执行了~~"); } // todo 全参构造方法 public Student(String name, Integer age) { this.name = name; this.age = age; System.out.println("全参构造器执行了~~~"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } };
-
-
运行结果如下
-