3-2-1 框架前置知识-反射

什么是反射Reflect

反射是在运行时动态访问类与对象的技术

反射是JDK1.2版本后的高级特性,隶属于java.lang.reflect

大多数框架都基于反射实现参数配置,动态注入等特性

反射核心类

Class类

Constructor构造方法类

Method方法类

Field成员变量类

实体类示例

 1 /**
 2  * 员工实体类
 3  */
 4 public class Employee {
 5     static {
 6         System.out.println("Employee类已被加载到jvm,并已初始化");
 7     }
 8     private Integer eno;
 9     public String ename;
10     private Float salary;
11     private String dname;
12 
13     public Employee(){
14         System.out.println("Employee默认构造方法已被执行");
15     }
16 
17     public Employee(Integer eno, String ename, Float salary , String dname){
18         this.eno = eno;
19         this.ename = ename;
20         this.salary = salary;
21         this.dname = dname;
22         System.out.println("Employee带参构造方法已被执行");
23     }
24 
25     public Integer getEno() {
26         return eno;
27     }
28 
29     public void setEno(Integer eno) {
30         this.eno = eno;
31     }
32 
33     public String getEname() {
34         return ename;
35     }
36 
37     public void setEname(String ename) {
38         this.ename = ename;
39     }
40 
41     public Float getSalary() {
42         return salary;
43     }
44 
45     public void setSalary(Float salary) {
46         this.salary = salary;
47     }
48 
49     public String getDname() {
50         return dname;
51     }
52 
53     public void setDname(String dname) {
54         this.dname = dname;
55     }
56 
57     @Override
58     public String toString() {
59         return "Employee{" +
60                 "eno=" + eno +
61                 ", ename='" + ename + '\'' +
62                 ", salary=" + salary +
63                 ", dname='" + dname + '\'' +
64                 '}';
65     }
66 
67     public Employee updateSalary(Float val){
68         this.salary = this.salary + val;
69         System.out.println(this.ename + "调薪至" + this.salary + "元");
70         return this;
71     }
72 }

Class类

Class是JVM中代表类和接口的类

Class对象具体包含了某个特定类的结构信息

通过Class对象可获取对应类的构造方法/方法/成员变量

 1 import com.mingm.learn.reflect.entity.Employee;
 2 
 3 /**
 4  * 无参构造方法创建对象
 5  */
 6 public class ClassSample {
 7 
 8     public static void main(String[] args) {
 9         try {
10             //Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
11             Class employeeClass = Class.forName("com.mingm.learn.reflect.entity.Employee");
12             System.out.println("Employee已被加载到jvm");
13             //newInstance通过默认构造方法创建新的对象
14             Employee emp = (Employee) employeeClass.newInstance();
15             System.out.println(emp);
16         } catch (ClassNotFoundException e) {
17             //类名与类路径书写错误是抛出"类无法找到"异常
18             e.printStackTrace();
19         } catch (IllegalAccessException e) {
20             //非法访问异常,当在作用域外访问对象方法或成员变量时抛出
21             e.printStackTrace();
22         } catch (InstantiationException e) {
23             //对象无法被实例化,抛出"实例化异常"
24             e.printStackTrace();
25         }
26     }
27 }

Constructor构造方法类

Constructor类对Java类中的构造方法的抽象

Construcor对象包含了具体类的某个具体构造方法的声明

通过Constructor对象调用带参方法构建对象

 1 import com.mingm.learn.reflect.entity.Employee;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.InvocationTargetException;
 5 
 6 /**
 7  * 利用带参构造方法创建对象
 8  */
 9 public class ConstructorSample {
10 
11     public static void main(String[] args) {
12         try {
13             Class employeeClass = Class.forName("com.mingm.learn.reflect.entity.Employee");
14             Constructor constructor = employeeClass.getConstructor(new Class[]{
15                     Integer.class, String.class, Float.class, String.class
16             });
17             Employee employee = (Employee)constructor.newInstance(new Object[]{
18                     100, "李磊", 3000f, "研发部"
19             });
20             System.out.println(employee);
21         } catch (ClassNotFoundException e) {
22             e.printStackTrace();
23         } catch (NoSuchMethodException e) {
24             //没有找到与之对应格式的方法
25             e.printStackTrace();
26         } catch (IllegalAccessException e) {
27             e.printStackTrace();
28         } catch (InstantiationException e) {
29             e.printStackTrace();
30         } catch (InvocationTargetException e) {
31             //当被调用的方法的内部抛出了异常而没有被捕获时
32             e.printStackTrace();
33         }
34     }
35 }

Method方法类

Method对象指代某个类方法的描述

Method对象使用classObj.getMethod()方法获取

通过Method对象调用指定对象的对应方法

 1 import com.mingm.learn.reflect.entity.Employee;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.InvocationTargetException;
 5 import java.lang.reflect.Method;
 6 
 7 /**
 8  * 利用Method方法类调用
 9  */
10 public class MethodSample {
11 
12     public static void main(String[] args) {
13         try {
14             Class employeeClass = Class.forName("com.mingm.learn.reflect.entity.Employee");
15             Constructor constructor = employeeClass.getConstructor(new Class[]{
16                     Integer.class, String.class, Float.class, String.class
17             });
18             Employee employee = (Employee)constructor.newInstance(new Object[]{
19                     100, "李磊", 3000f, "研发部"
20             });
21             Method employeeClassMethod = employeeClass.getMethod("updateSalary", new Class[]{
22                     Float.class
23             });
24             Employee employee1 = (Employee)employeeClassMethod.invoke(employee, new Object[]{1000f});
25             System.out.println(employee1);
26         } catch (ClassNotFoundException e) {
27             e.printStackTrace();
28         } catch (NoSuchMethodException e) {
29             e.printStackTrace();
30         } catch (IllegalAccessException e) {
31             e.printStackTrace();
32         } catch (InstantiationException e) {
33             e.printStackTrace();
34         } catch (InvocationTargetException e) {
35             e.printStackTrace();
36         }
37     }
38 }

Field成员变量类

Field对应某个具体类中成员变量的声明

Field对象使用classObj.getField()方法获取

通过Field对象可为某对象成员变量赋值/取值

 1 /**
 2  * 利用Field对成员变量赋值/取值
 3  */
 4 public class FieldSample {
 5 
 6     public static void main(String[] args) {
 7         try {
 8             Class employeeClass = Class.forName("com.mingm.learn.reflect.entity.Employee");
 9             Constructor constructor = employeeClass.getConstructor(new Class[]{
10                     Integer.class,String.class,Float.class,String.class
11             });
12             Employee employee = (Employee) constructor.newInstance(new Object[]{
13                     100,"李磊",3000f,"研发部"
14             });
15             Field enameField = employeeClass.getField("ename");
16             enameField.set(employee, "李雷");
17             String ename = (String)enameField.get(employee);
18             System.out.println("ename:" + ename);
19         } catch (ClassNotFoundException e) {
20             e.printStackTrace();
21         } catch (NoSuchMethodExcseption e) {
22             e.printStackTrace();
23         } catch (InstantiationException e) {
24             e.printStackTrace();
25         } catch (IllegalAccessException e) {
26             e.printStackTrace();
27         } catch (InvocationTargetException e) {
28             e.printStackTrace();
29         } catch (NoSuchFieldException e) {
30             //没有找到对应成员变量时抛出的异常
31             e.printStackTrace();
32         }
33     }
34 }

getDeclared系列方法说明

getDeclaredConstructor(s)|Method(s)|Field(s)获取对应对象

getConstructor(s)|Method(s)|Field(s)只能获取public对象

访问非作用域内构造方法,方法,成员变量会抛出异常

 1 import com.mingm.learn.reflect.entity.Employee;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Field;
 5 import java.lang.reflect.InvocationTargetException;
 6 import java.lang.reflect.Method;
 7 
 8 /**
 9  * 获取对象所有成员变量值
10  */
11 public class GetDeclaredSample {
12 
13     public static void main(String[] args) {
14         try {
15             Class employeeClass = Class.forName("com.mingm.learn.reflect.entity.Employee");
16             Constructor constructor = employeeClass.getConstructor(new Class[]{
17                     Integer.class, String.class, Float.class, String.class
18             });
19             Employee employee = (Employee) constructor.newInstance(new Object[]{
20                     100, "李磊", 3000f, "研发部"
21             });
22             //获取当前类所有成员变量
23             Field[] fields = employeeClass.getDeclaredFields();
24             for (Field field:fields) {
25 //                System.out.println(field.getName());
26                 if (field.getModifiers() == 1) { //pubilc修饰
27                     Object val = field.get(employee);
28                     System.out.println(field.getName() + ":" + val);
29                 } else if (field.getModifiers() == 2) { //private修饰
30                     String methodName = "get" + field.getName().substring(0,1).toUpperCase()
31                             + field.getName().substring(1);
32                     Method getMethod = employeeClass.getMethod(methodName);
33                     Object ret = getMethod.invoke(employee);
34                     System.out.println(field.getName() + ":" + ret);
35                 }
36             }
37         } catch (ClassNotFoundException e) {
38             e.printStackTrace();
39         } catch (NoSuchMethodException e) {
40             e.printStackTrace();
41         } catch (InstantiationException e) {
42             e.printStackTrace();
43         } catch (IllegalAccessException e) {
44             e.printStackTrace();
45         } catch (InvocationTargetException e) {
46             e.printStackTrace();
47         }
48     }
49 }

 

posted @ 2020-09-23 19:33  mingmingn  阅读(170)  评论(0)    收藏  举报