不得不说那点小事--反射基础

书到用时方恨少啊!每次用到反射时都要百度查,留个备份在这,也省得去看别人的总结了。

一、反射中重要的几个类
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 }
View Code
二、通过反射获取类并初始化
 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 }
View Code
运行结果:


三、通过反射获取类信息(类名、属性、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 }
View Code

运行结果:

posted @ 2018-11-26 18:07  爱吃醋的兔子  阅读(365)  评论(0编辑  收藏  举报