不得不说那点小事--反射基础
书到用时方恨少啊!每次用到反射时都要百度查,留个备份在这,也省得去看别人的总结了。
一、反射中重要的几个类
Constructor:代表类的单个构造方法,通过Constructor我们可执行一个类的某个构造方法(有参或者无参)来创建对象时。
Method:代表类中的单个方法,可以用于执行类的某个普通方法,有参或无参,并可以接收返回值。
Field:代表类中的单个属性,用于set或get属性
AccessibleObject:以上三个类的父类,提供了构造方法,普通方法,和属性的访问控制的能力。
使用Class类中的方法可以获得该类中的所有Constructor对象,Method对象,和Field对象。但是任然无法访问私有化的构造方法,普通方法,和私有属性,
此时我们可以使用他们继承父类(AccessibleObject)中的setAccessible()方法,来设置或取消访问检查,以达到访问私有对象的目的。
这里呢,先布出我们的使用的Bean,以下都是通过当前实体类进行反射操作的示例
1 package com.example.demo.test;
2
3 import java.io.Serializable;
4
5 /**
6 * @description: 反射用到的类
7 * @author: The Queen Of Rabbit
8 * @date: 2018/11/26
9 */
10 public class EvalNum implements Serializable {
11
12 private String pro;
13 protected String range;
14 String score;
15 public String comment;
16 static String value;
17
18 public EvalNum() {
19 super();
20 }
21
22 public EvalNum(String pro, String range, String score, String comment) {
23 super();
24 this.pro = pro;
25 this.range = range;
26 this.score = score;
27 this.comment = comment;
28 }
29
30 public String getPro() {
31 return pro;
32 }
33
34 public void setPro(String pro) {
35 this.pro = pro;
36 }
37
38 public String getRange() {
39 return range;
40 }
41
42 public void setRange(String range) {
43 this.range = range;
44 }
45
46 public String getScore() {
47 return score;
48 }
49
50 public void setScore(String score) {
51 this.score = score;
52 }
53
54 public String getComment() {
55 return comment;
56 }
57
58 public void setComment(String comment) {
59 this.comment = comment;
60 }
61
62 public static String getValue() {
63 return value;
64 }
65
66 public static void setValue(String value) {
67 EvalNum.value = value;
68 }
69
70 @Override
71 public String toString() {
72 return "EvalNum{" +
73 "pro='" + pro + '\'' +
74 ", range='" + range + '\'' +
75 ", score='" + score + '\'' +
76 ", comment='" + comment + '\'' +
77 '}';
78 }
79 }
二、通过反射获取类并初始化
1 package com.example.demo.test;
2
3 /**
4 * @description: Reflect Demo
5 * @author: The Queen Of Rabbit
6 * @date: 2018/11/26
7 */
8 public class Reflect {
9
10 public static void main(String[] args) {
11 // 通过反射获取类并初始化
12 try {
13 // 方式一:Class.forName(className); 参数className结构: 完整的包名.类名
14 String path = "com.example.demo.test.EvalNum";
15 Class<?> optionOneClass = Class.forName(path);
16 System.out.println("方案一:" + optionOneClass);
17
18 // 方式二:T.class;
19 Class<EvalNum> optionTwoClass = EvalNum.class;
20 System.out.println("方案二:" + optionTwoClass);
21
22 // 方式三:(new T()).getClass();
23 EvalNum reflect = new EvalNum();
24 Class<? extends EvalNum> optionThreeClass = reflect.getClass();
25 System.out.println("获取:" + optionThreeClass);
26
27 } catch (Exception e) {
28 e.printStackTrace();
29 }
30 }
31 }
运行结果:
三、通过反射获取类信息(类名、属性、getter/setter、构造方法)
1 package com.example.demo.test;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.Method;
6
7 /**
8 * @description: Reflect Demo
9 * @author: The Queen Of Rabbit
10 * @date: 2018/11/26
11 */
12 public class Reflect {
13
14 public static void main(String[] args) {
15 try {
16 // 通过反射获取类信息
17 String path = "com.example.demo.test.EvalNum";
18 Class<?> reflectClass = Class.forName(path);
19
20 // 完整的包名
21 String name = reflectClass.getName();
22 System.out.println("获取完整的包名:\n\t\t" + name);
23
24 // 类名
25 String simpleName = reflectClass.getSimpleName();
26 System.out.println("获取类名:\n\t\t" + simpleName);
27
28 // 属性为public的字段
29 Field[] fields = reflectClass.getFields();
30 System.out.println("获取属性为public的字段:");
31 for (Field field : fields) {
32 System.out.println("\t\t" + field);
33 }
34
35 // 所有的属性
36 Field[] declaredFields = reflectClass.getDeclaredFields();
37 System.out.println("获取所有的属性:");
38 for (Field field : declaredFields) {
39 System.out.println("\t\t" + field);
40 }
41
42 // 指定属性
43 Field pro = reflectClass.getDeclaredField("pro");
44 System.out.println("获取指定属性:\n\t\t" + pro);
45
46 // public方法
47 Method[] declaredMethods = reflectClass.getDeclaredMethods();
48 System.out.println("获取public方法:");
49 for (Method method : declaredMethods) {
50 System.out.println("\t\t" + method);
51 }
52
53 // 指定方法 获取getPro方法,如果没有参数,就默认为null
54 Method getPro = reflectClass.getDeclaredMethod("getPro", null);
55 System.out.println("获取指定方法:\n\t\t" + getPro);
56
57 // 无参构造方法
58 EvalNum reflect = (EvalNum) reflectClass.newInstance();
59 System.out.println("获取无参构造方法:\n\t\t" + reflect);
60
61 // 指定构造方法 获取参数为(String,String,String, String)的构造方法
62 Constructor<?> declaredConstructor = reflectClass.getDeclaredConstructor(String.class, String.class, String.class, String.class);
63 System.out.println("获取指定构造方法:\n\t\t" + declaredConstructor);
64
65 // 通过反射调用普通方法
66 EvalNum evalNum = (EvalNum) reflectClass.newInstance();
67 Method proMethod = reflectClass.getDeclaredMethod("setValue", String.class);
68 // 把对象evalNum的pro设置为属性(仅用于static修饰的属性)
69 proMethod.invoke(evalNum, "属性");
70
71 // 获取pro值
72 Field field = reflectClass.getDeclaredField("value");
73 // 仅在获取用private修饰属性使用
74 field.setAccessible(true);
75 String value = (String) field.get(reflectClass.newInstance());
76 // 仅静态字段可传null
77 String staticValue = (String) field.get(null);
78 System.out.println("获取value值:\n\t\t" + value);
79 System.out.println("获取staticValue值:\n\t\t" + staticValue);
80
81 // 通过反射操作普通的属性
82 EvalNum evalNumOne = (EvalNum) reflectClass.newInstance();
83 Field proField = reflectClass.getDeclaredField("pro");
84 // 仅在获取用private修饰属性使用
85 proField.setAccessible(true);
86 proField.set(evalNumOne, "石头");
87 System.out.println("获取pro值:\n\t\t" + evalNumOne.getPro());
88
89 } catch (Exception e) {
90 e.printStackTrace();
91 }
92 }
93 }
运行结果: