反射API操作属性、方法、构造器

个人对反射的理解:

  反射是在运行中,可以获取一个类的所有属性和方法,并且可以操作该类的所有属性和方法。

  和new关键字不同,new关键字无法获取private修饰的属性和方法及构造器,但是反射能;在使用new关键字时,不知道类名是无法new的,但是反射在不知道类名时也可以使用,这也是spring框架中的控制反转(IOC)的核心机制。

正文:

  一、首先创建一个beanDemo:

 1 package fanShe;
 2 
 3 public class User {
 4 
 5     private int id;
 6     public String name;
 7     private int age;
 8     
 9     public int getId() {
10         return id;
11     }
12     public void setId(int id) {
13         this.id = id;
14     }
15     public void setId() {
16         this.id = 1;
17     }
18     public String getName() {
19         return name;
20     }
21     public void setName(String name) {
22         this.name = name;
23     }
24     public int getAge() {
25         return age;
26     }
27     public void setAge(int age) {
28         this.age = age;
29     }
30     
31     public User(int id, String name, int age) {
32         this.id = id;
33         this.name = name;
34         this.age = age;
35     }
36     
37     public User() {
38         
39     }
40     
41     
42 }

  二、使用反射API对bean的属性、方法、构造器进行操作

 1 import java.lang.reflect.Constructor;
 2 import java.lang.reflect.Field;
 3 import java.lang.reflect.Method;
 4 
 5 public class Demo01 {
 6     
 7     public static void main(String[] args) {
 8         String path = "fanShe.User";
 9         try {
10             //反射
11             Class clazz = Class.forName(path);
12             //获取包名+类名
13             System.out.println(clazz.getName());
14             //获取类名
15             System.out.println(clazz.getSimpleName());
16             
17             /**
18              * 获取属性
19              */
20             //获取只能是public的属性
21             Field[] fields = clazz.getFields();
22             System.out.println(fields.length);
23             //获取类下所有的属性(包括私有属性)
24             Field[] declaredFields = clazz.getDeclaredFields();
25             System.out.println(declaredFields.length);
26             for (Field field : declaredFields) {
27                 System.out.println(field);
28             }
29             
30             /**
31              * 获取方法
32              */
33             //获取该类的所有的public的方法,包括默认继承的Object类
34             Method[] methods = clazz.getMethods();
35             System.out.println(methods.length);
36             //获取该类的所有的方法(不包括构造方法和Object的方法)
37             Method[] declaredMethods = clazz.getDeclaredMethods();
38             for (Method method : declaredMethods) {
39                 System.out.println(method);
40             }
41             System.out.println(declaredMethods.length);
42             //获取指定的方法(第一个参数为方法名称,第二个参数为该方法中的参数类型,如果没有就填null,目的是防止重载找不到目标方法)
43             clazz.getDeclaredMethod("setId", int.class);
44             
45             /**
46              * 获取构造器
47              */
48             //获取该类的public的构造器
49             Constructor[] constructors = clazz.getConstructors();
50             System.out.println(constructors.length);
51             //获取该类下的所有构造器
52             Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
53             for (Constructor constructor : declaredConstructors) {
54                 System.out.println(constructor);
55             }
56             //获取指定的构造器(参数为该构造器中的参数的类型,如果该构造器没有参数,则填null)
57             Constructor declaredConstructor = clazz.getDeclaredConstructor(int.class,String.class,int.class);
58             System.out.println(declaredConstructor);
59             
60             
61             /**
62              * 通过反射API调用构造方法,构造对象
63              */
64             User user1 = (User) clazz.newInstance(); //调用类的无参构造
65             System.out.println(user1);
66             //获取指定的构造器后,可通过newInstance传入具体的值给对象进行赋值
67             User user2 = (User) declaredConstructor.newInstance(10,"张三丰",20);
68             //赋值后可调用方法获取数据
69             System.out.println(user2.getName());
70             //动态获取方法
71             Method declaredMethod = clazz.getDeclaredMethod("setName", String.class);
72             declaredMethod.invoke(user2, "丰是");    //通过方法给该属性赋值
73             System.out.println(user2.getName());
74             
75             /**
76              * 通过反射API操作属性
77              */
78             User user3 = (User) clazz.newInstance(); //调用类的无参构造
79             Field field = clazz.getDeclaredField("age");
80             field.setAccessible(true); //因为私有的属性是不能被操作的,但是反射有办法,将该属性设置为不必检查,可以直接访问
81             field.set(user3, 18);    //通过反射写属性
82             System.out.println(user3.getAge());    //普通方法调用
83             System.out.println(field.get(user3));//通过反射API调用
84             
85             
86         } catch (Exception e) {
87             e.printStackTrace();
88         }
89     }
90 }

 

posted @ 2020-08-06 23:46  梅竹疯狂打豆豆  阅读(190)  评论(0)    收藏  举报