2022.4.20 反射获取构造方法、成员变量、成员方法

 获取构造方法

规则:

get表示获取

Declared表示私有

最后的s表示所有,复数形式

如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

方法名说明
Constructor<?>[] getConstructors() 获得所有的构造(只能public修饰)
Constructor<?>[] getDeclaredConstructors() 获得所有的构造(包含private修饰)
Constructor<T> getConstructor(Class<?>... parameterTypes) 获取指定构造(只能public修饰)
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取指定构造(包含private修饰)

在api帮助文档中搜索常量字段值:权限修饰符对应的常量值

代码示例:

Student

复制代码
 1 package com.xing.reflect;
 2  3 import lombok.Data;
 4  5 @Data
 6 public class Student {
 7     private String name;
 8     private int age;
 9 10     public Student() {
11     }
12 13     public Student(String name) {
14         this.name = name;
15     }
16 17     protected Student(int age) {
18         this.age = age;
19     }
20 21     private Student(String name, int age) {
22         this.name = name;
23         this.age = age;
24     }
25 26 }
复制代码

GetConstructor

复制代码
  1 package com.xing.reflect;
  2   3   4 import java.lang.reflect.Constructor;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.lang.reflect.Parameter;
  7   8 public class GetConstructor {
  9     public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 10     /*
 11         Class类中用于获取构造方法的方法
 12             Constructor<?>[] getConstructors()                                返回所有公共构造方法对象的数组
 13             Constructor<?>[] getDeclaredConstructors()                        返回所有构造方法对象的数组
 14             Constructor<T> getConstructor(Class<?>... parameterTypes)         返回单个公共构造方法对象
 15             Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造方法对象
 16  17  18         Constructor类中用于创建对象的方法
 19             T newInstance(Object... initargs)                                 根据指定的构造方法创建对象
 20             setAccessible(boolean flag)                                       设置为true,表示取消访问检查
 21     */
 22  23         //1.获取class字节码文件对象
 24         Class<?> clazz = Class.forName("com.xing.reflect.Student");
 25  26         //2.获取构造方法
 27         Constructor<?>[] cons1 = clazz.getConstructors();
 28         for (Constructor<?> con : cons1) {
 29             System.out.println(con);
 30             /*  public com.xing.reflect.Student(java.lang.String)
 31                 public com.xing.reflect.Student() */
 32         }
 33         System.out.println("===================================");
 34  35         Constructor<?>[] cons2 = clazz.getDeclaredConstructors();
 36         for (Constructor<?> con : cons2) {
 37             System.out.println(con);
 38             /*  private com.xing.reflect.Student(java.lang.String,int)
 39                 protected com.xing.reflect.Student(int)
 40                 public com.xing.reflect.Student(java.lang.String)
 41                 public com.xing.reflect.Student() */
 42         }
 43  44         System.out.println("===================================");
 45         // 只获取空参
 46         Constructor<?> con1 = clazz.getDeclaredConstructor();
 47         System.out.println(con1);
 48  49         // 获取name的  根据其类型
 50         Constructor<?> con2 = clazz.getDeclaredConstructor(String.class);
 51         System.out.println(con2);
 52  53         //  获取int的  根据其类型
 54         Constructor<?> con3 = clazz.getDeclaredConstructor(int.class);
 55         System.out.println(con3);
 56  57         // 获取 name和int的
 58         Constructor<?> con4 = clazz.getDeclaredConstructor(String.class,int.class);
 59         System.out.println(con4);
 60         System.out.println("===================================");
 61  62         // 获取权限修饰符  1-public 2-private 4-protected
 63         int modifiers = con4.getModifiers();
 64         System.out.println(modifiers);//2
 65  66         System.out.println("===================================");
 67  68         // 获取构造方法的所有参数
 69         Parameter[] parameters = con4.getParameters();
 70         for (Parameter parameter : parameters) {
 71             System.out.println(parameter);
 72             /* java.lang.String name
 73                 int age */
 74         }
 75         System.out.println("===================================");
 76  77         // 获取构造方法参数个数
 78         int parameterCount = con4.getParameterCount();
 79         System.out.println(parameterCount);//2
 80         System.out.println("===================================");
 81  82         // 获取参数类型
 83         Class<?>[] parameterTypes = con4.getParameterTypes();
 84         for (Class<?> type : parameterTypes) {
 85             System.out.println(type);
 86             /* class java.lang.String
 87  88                 int */
 89         }
 90         System.out.println("===================================");
 91  92         //暴力反射:表示临时取消权限校验   因为con4 是私有的构造方法  不能直接通过其构造方法创建对象
 93         con4.setAccessible(true);
 94         // 通过构造方法创建对象   传入此构造方法的参数
 95         Student stu = (Student) con4.newInstance("张三", 23);
 96  97         System.out.println(stu);
 98  99 100     }
101 }
复制代码

获取成员变量

规则:

get表示获取

Declared表示私有

最后的s表示所有,复数形式

如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

方法名:

方法名说明
Field[] getFields() 返回所有成员变量对象的数组:获取类中public类型的属性, 包括父类中的字段。 返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问的成员变量
Field[] getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到:获取类中所有的属性(public、protected、default、private),但不包括继承的属性, 返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有成员变量(包括私有
Field getField(String name) 返回单个成员变量对象(只能拿public的):返回一个类或接口 及其父类的public成员变量 ,私有成员变量报错。 返回一个 Field 对象
Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到:仅能获取类或接口本身的成员变量 , 返回一个 Field 对象,该对象返回此 Class 对象所表示的类或接口的指定已声明成员变量(包括私有)。

Field 类对象常用方法

  • 获取变量的类型:

    • Field.getType():返回这个变量的类型

    • Field.getGenericType():如果当前属性有签名属性类型就返回,否则就返回 Field.getType()

    • isEnumConstant() : 判断这个属性是否是枚举类

  • 获取成员变量的修饰符

    • Field.getModifiers() 以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符

  • 获取和修改成员变量的值

    • getName() : 获取属性的名字

    • get(Object obj) 返回指定对象obj上此 Field 表示的字段的值

    • set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值

代码示例:

Person

复制代码
 1 package com.xing.reflect;
 2  3 import lombok.Data;
 4  5 @Data
 6 public class Person {
 7     private String name;
 8     private int age;
 9     public String gerder;
10 11     public Person() {
12     }
13 14     public Person(String name, int age, String gerder) {
15         this.name = name;
16         this.age = age;
17         this.gerder = gerder;
18     }
19 }
复制代码

GetField

复制代码
 1 package com.xing.reflect;
 2  3 import java.lang.reflect.Field;
 4  5 public class GetField {
 6     public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
 7         /*
 8            Class类中用于获取成员变量的方法
 9                 Field[] getFields():                返回所有公共成员变量对象的数组
10                 Field[] getDeclaredFields():        返回所有成员变量对象的数组
11                 Field getField(String name):        返回单个公共成员变量对象
12                 Field getDeclaredField(String name):返回单个成员变量对象
13 14            Field类中用于创建对象的方法
15                 void set(Object obj, Object value):赋值
16                 Object get(Object obj)              获取值
17 18         */
19 20         //1.获取class字节码文件的对象
21         Class<?> clazz = Class.forName("com.xing.reflect.Person");
22 23         //2.获取公共的成员变量
24         Field[] fields1 = clazz.getFields();
25         for (Field field : fields1) {
26             System.out.println(field);//public java.lang.String com.xing.reflect.Person.gerder
27         }
28         System.out.println("=========================");
29 30         //3.获取所有的成员变量(包括私有的)
31         Field[] fields = clazz.getDeclaredFields();
32         for (Field field : fields) {
33             System.out.println(field);
34         }
35         System.out.println("=========================");
36 37         //4. 获取单个公共的成员变量
38         Field gerder = clazz.getField("gerder");
39         System.out.println(gerder);
40         System.out.println("=========================");
41 42         //5. 获取单个的成员变量(包括私有的)
43         Field name = clazz.getDeclaredField("name");
44         System.out.println(name);
45         System.out.println("=========================");
46 47         //获取权限修饰符 1-public 2-private 4-protected
48         int modifiers = name.getModifiers();
49         System.out.println(modifiers);
50         System.out.println("=========================");
51 52         //获取成员变量的名字
53         String n = name.getName();
54         System.out.println(n);
55         System.out.println("=========================");
56 57         //获取成员变量的数据类型
58         Class<?> type = name.getType();
59         System.out.println(type);//class java.lang.String
60         System.out.println("=========================");
61 62 63         //获取成员变量记录的值
64         Person s = new Person("zhangsan",23,"男");
65         // 暴力反射:表示临时取消权限校验   因为name 是私有的成员变量
66         name.setAccessible(true);
67         // 获取s这个对象中name这个成员变量的具体值
68         String value = (String) name.get(s);
69         System.out.println(value);//zhangsan
70         System.out.println("=========================");
71 72         //修改对象里面记录的值  参数1:修改哪个对象的值   参数2: 将值修改为什么
73         name.set(s,"lisi");
74         System.out.println(s);//Person(name=lisi, age=23, gerder=男)
75 76     }
77 }
复制代码

 获取成员方法

规则:

get表示获取

Declared表示私有

最后的s表示所有,复数形式

如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

方法名说明
Method[] getMethods() 返回所有成员方法对象的数组(只能拿public的,包含父类中所有的公共方法)
Method[] getDeclaredMethods() 获取里面所有的方法对象(不能获取父类的方法,但是可以获取本类中私有的方法)
Method getMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象,存在就能拿到

代码示例:

Cat

复制代码
 1 package com.xing.reflect;
 2  3 import lombok.AllArgsConstructor;
 4 import lombok.Data;
 5 import lombok.NoArgsConstructor;
 6  7 @Data
 8 @NoArgsConstructor
 9 @AllArgsConstructor
10 public class Cat {
11     private String name;
12     private int age;
13 14     public void sleep(){
15         System.out.println("睡觉");
16     }
17 18     private String eat(String something){
19         System.out.println("在吃" + something);
20         return "奥利给";
21     }
22 23     private void eat(String something,int a) {
24         System.out.println("在吃" + something);
25     }
26 }
27
复制代码

GetMethod

复制代码
 1 package com.xing.reflect;
 2  3  4 import java.lang.reflect.InvocationTargetException;
 5 import java.lang.reflect.Method;
 6 import java.lang.reflect.Parameter;
 7  8 public class GetMethod {
 9     public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
10     /*
11        Class类中用于获取成员方法的方法
12             Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
13             Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
14             Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
15             Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
16     */
17 18         //1. 获取class字节码文件对象
19         Class<?> clazz = Class.forName("com.xing.reflect.Cat");
20 21 22         //2. 获取里面所有公共的方法对象(包含父类中所有的公共方法)
23         Method[] methods = clazz.getMethods();
24         for (Method method : methods) {
25             System.out.println(method);
26         }
27         System.out.println("==================================");
28 29         //3.获取里面所有的方法对象(不能获取父类的方法,但是可以获取本类中私有的方法)
30         Method[] methods2 = clazz.getDeclaredMethods();
31         for (Method method : methods2) {
32             System.out.println(method);
33         }
34         System.out.println("==================================");
35 36         //4. 获取指定的单一方法  参数1:方法的名字  参数2:方法形参
37         Method method = clazz.getDeclaredMethod("eat", String.class);
38         System.out.println(method);
39         System.out.println("==================================");
40 41         // 获取方法的修饰符
42         int modifiers = method.getModifiers();
43         System.out.println(modifiers);
44         System.out.println("==================================");
45 46         // 获取方法的名字
47         String name = method.getName();
48         System.out.println(name);//eat
49         System.out.println("==================================");
50 51         // 获取方法的形参
52         Parameter[] parameters = method.getParameters();
53         for (Parameter parameter : parameters) {
54             System.out.println(parameter);
55         }
56         System.out.println("==================================");
57 58         //获取方法的抛出的异常
59         Class<?>[] exceptionTypes = method.getExceptionTypes();
60         for (Class<?> exceptionType : exceptionTypes) {
61             System.out.println(exceptionType);
62         }
63         System.out.println("==================================");
64 65         //方法运行
66         /*Method类中用于创建对象的方法
67         Object invoke(Object obj, Object... args):运行方法
68         参数一:用obj对象调用该方法
69         参数二:调用方法时传递的参数(如果没有就不写)
70         返回值:方法的返回值(如果没有就不写)*/
71 72 73         Cat cat = new Cat();
74         // 因为method返回的方法是私有的
75         method.setAccessible(true);
76         //参数一s:表示方法的调用者
77         //参数二"汉堡包":表示在调用方法的时候传递的实际参数
78 79         // cat这个对象调用method返回的eat方法,并给eat方法传递一个参数”汉堡包“
80         String result = (String) method.invoke(cat, "汉堡包");//在吃汉堡包
81         System.out.println(result);// 打印的方法的返回值:奥利给
82 83 84     }
85 }
复制代码
  • 调用指定的方法 通过反射,调用类中的方法,通过Method类完成。

    • 通过Class类的getMethod(String name,Class...parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。

    • 之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

  • Object invoke(Object obj, Object ... args)

    • Object对应原方法的返回值,若原方法无返回值,此时返回null

    • 若原方法若为静态方法,此时形参Object obj可为null

    • 若原方法形参列表为空,则Object[] args为null

    • 若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。

  • setAccessible

    • Method和Field、Constructor对象都有setAccessible()方法。

    • setAccessible作用是启动和禁用访问安全检查的开关。

    • 参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。

      • 提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。

      • 使得原本无法访问的私有成员也可以访问

    • 参数值为false则指示反射的对象应该实施Java语言访问检查

 

posted @   暴躁C语言  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示