目录
java反射通俗来讲就是解剖类,并允许以编程的方式解剖类中的各个成分(构造器,成员变量,方法)。
获取类的信息,并操作他们
第一步:加载类,获取类的字节码:Class对象
第二步:获取类的构造器:Constructor对象
第三步:获取类的成员变量:Field对象
第四步:获取类的成员方法:Method对象
- public static void main(String[] args) throws Exception {
- Student stu = new Student();
- //第一种方式,类名.的方式
- Class
studentClass = Student.class; - //通过类对象,获得类名
- String simpleName = studentClass.getSimpleName();
- //通过类对象,获取全类名
- String name = studentClass.getName();
-
- //第二种方式,调用Class提供的方法
- Class studentClass2 = Class.forName("com.example.com.yunlong.test4.Student");
-
- //第三种方式,Object提供的方法:public Class getClass();
- Class studentClass3 = stu.getClass();
- }
第一步:获取class对象
第二步:通过 Class 对象,我们可以获取构造器信息。
getConstructors():获取全部的公共构造器。getDeclaredConstructors():获取全部的构造器,包括私有的。getConstructor(Class>... parameterTypes):获取指定参数类型的公共构造器。getDeclaredConstructor(Class>... parameterTypes):获取指定参数类型的所有构造器,包括私有构造器。第一步:获取class对象
第二步:通过 Class 对象,我们可以获取成员变量信息。
getFields():获取全部的公共字段。getDeclaredFields():获取全部的字段,包括私有的。getField(String name):获取指定名称的公共字段。getDeclaredField(String name):获取指定名称的所有字段,包括私有字段。- import java.lang.reflect.Field;
-
- class MyClass {
- public String publicField;
- private int privateField;
-
- public MyClass(String publicField, int privateField) {
- this.publicField = publicField;
- this.privateField = privateField;
- }
- }
-
- public class Main {
- public static void main(String[] args) throws Exception {
- // 创建 MyClass 类的实例
- MyClass obj = new MyClass("publicValue", 123);
-
- // 获取 MyClass 类的 Class 对象
- Class> clazz = MyClass.class;
-
- // 获取指定名称的公共字段
- Field publicField = clazz.getField("publicField");
-
- // 获取指定名称的所有字段,包括私有字段
- Field privateField = clazz.getDeclaredField("privateField");
-
- // 设置字段的可访问性,以便访问私有字段
- privateField.setAccessible(true);
-
- // 获取字段的值
- Object publicValue = publicField.get(obj);
- Object privateValue = privateField.get(obj);
-
- // 输出字段的值
- System.out.println("Public Field Value: " + publicValue);
- System.out.println("Private Field Value: " + privateValue);
- }
- }
第一步:获取class对象
第二步:通过 Class 对象,我们可以获取类中方法信息。
getMethods():获取类的全部公共方法。getDeclaredMethods():获取类的全部方法,包括私有。getMethod(String name, Class>... parameterTypes):获取指定名称和参数类型的公共方法。getDeclaredMethod(String name, Class>... parameterTypes):获取指定名称和参数类型的所有方法,包括私有方法。- import java.lang.reflect.Method;
-
- class MyClass {
- public void publicMethod(String param1, int param2) {
- System.out.println("Public Method: " + param1 + ", " + param2);
- }
-
- private void privateMethod() {
- System.out.println("Private Method");
- }
- }
-
- public class Main {
- public static void main(String[] args) throws Exception {
- // 创建 MyClass 类的实例
- MyClass obj = new MyClass();
-
- // 获取 MyClass 类的 Class 对象
- Class> clazz = MyClass.class;
-
- // 获取指定名称和参数类型的公共方法
- Method publicMethod = clazz.getMethod("publicMethod", String.class, int.class);
-
- // 获取指定名称和参数类型的所有方法,包括私有方法
- Method privateMethod = clazz.getDeclaredMethod("privateMethod");
-
- // 设置私有方法可访问
- privateMethod.setAccessible(true);
-
- // 调用公共方法
- publicMethod.invoke(obj, "param1", 123);
-
- // 调用私有方法
- privateMethod.invoke(obj);
- }
- }
基本作用:可以得到一个类的全部成分然后操作。
可以破坏封装性:因为它可以访问和操作类的私有成员,而不受java语言访问修饰符的限制
最重要的用途:适合做java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。
Java 反射广泛应用于以下几个领域:
实例
使用反射做一个简易版的框架
需求:对于任意一个对象,该框架都可以把对象的字段名和对应的值,保存到文件中去。
- public class MyFrame {
-
- public static void saveObject(Object obj) throws Exception {
- PrintStream ps = new PrintStream(new FileOutputStream("E:\\workspacelong\\Thred\\src\\data.txt",true));
- //第一步,拿到class对象
- Class> a = obj.getClass();
- String simpleName = a.getSimpleName();//拿到类名
- ps.println("------------"+simpleName+"-------------");
- //第二步,拿到类中成员变量
- Field[] declaredFields = a.getDeclaredFields();
- for (Field declaredField : declaredFields) {
- declaredField.setAccessible(true);
- //第三步,拿到成员变量的名字
- String name = declaredField.getName();
- //第四步,拿到成员变量的值,转化为String
- String value = declaredField.get(obj)+"";
- ps.println(name+"="+value);
- }
- ps.close();
- }
- }
尽管 Java 反射提供了强大的功能,但也存在一些优缺点:
优点:
缺点: