JAVA反射获取Constructor、Field、Method对象

王柳  金牌会员 | 2022-6-23 10:02:59 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 542|帖子 542|积分 1626

在实际开发中,通过反射可以得到一个类的完整结构,包括类的构造方法、类的属性、类的方法,这就需要使用到java.lang.reflect包中的以下几个类:
  1、Constructor:表示类中的构造方法
  2、Field:表示类中的属性
  3、Method:表示类中的方法
    目录
  1、使用反射技术获取构造器对象并使用
  2、使用反射技术获取成员变量对象并使用
  3、使用反射技术获取方法对象并使用
    使用反射技术获取构造器对象并使用

  实验类:
  1. public class 反射机制_2实验类 {
  2.     private String name;
  3.     private int age;
  4.     private 反射机制_2实验类() {
  5.         System.out.println("无参构造器执行!");
  6.     }
  7.     public 反射机制_2实验类(String name, int age) {
  8.         System.out.println("有参构造器执行!");
  9.         this.name = name;
  10.         this.age = age;
  11.     }
  12.     public String getName() {
  13.         return name;
  14.     }
  15.     public void setName(String name) {
  16.         this.name = name;
  17.     }
  18.     public int getAge() {
  19.         return age;
  20.     }
  21.     public void setAge(int age) {
  22.         this.age = age;
  23.     }
  24.     @Override
  25.     public String toString() {
  26.         return "反射机制_2实验类{" +
  27.                 "name='" + name + '\'' +
  28.                 ", age=" + age +
  29.                 '}';
  30.     }
  31. }
复制代码
   获取构造器对象:
  1. import org.junit.Test;
  2. import java.lang.reflect.Constructor;
  3. public class 反射机制_2构造器获取对象 {
  4.     //1、getConstructors
  5.     //获取全部的构造器,只能获取public修饰的构造器
  6.     @Test
  7.     public void getConstructors(){
  8.         //获取类对象
  9.         Class c=反射机制_2实验类.class;
  10.         //提取类中的全部的构造器对象(这里只能拿public修饰的构造器)
  11.         Constructor[] constructors=c.getConstructors();
  12.         //遍历构造器
  13.         for (Constructor constructor : constructors) {
  14.             System.out.println(constructor.getName()+"\t构造器参数个数为:"+constructor.getParameterCount()+"个");
  15.         }
  16.         //运行结果:IT2.反射机制_2实验类        构造器参数个数为:2个
  17.     }
  18.     //2、getDeclaredConstructors
  19.     //获取全部的构造器:只要你敢写,这里就能拿到,无所谓权限是否可及
  20.     @Test
  21.     public void getDeclaredConstructors(){
  22.         //获取类对象
  23.         Class c=反射机制_2实验类.class;
  24.         //提取类中的全部的构造器对象
  25.         Constructor[] constructors=c.getDeclaredConstructors();
  26.         //遍历构造器
  27.         for (Constructor constructor : constructors) {
  28.             System.out.println(constructor.getName()+"\t构造器参数个数为:"+constructor.getParameterCount()+"个");
  29.         }
  30.         //运行结果:
  31.         // IT2.反射机制_2实验类        构造器参数个数为:0个
  32.         // IT2.反射机制_2实验类        构造器参数个数为:2个
  33.     }
  34.     //3、getConstructor
  35.     //获取某个构造器:只能拿Public修饰的某个构造器
  36.     @Test
  37.     public void getConstructor() throws Exception {
  38.         //获取类对象
  39.         Class c=反射机制_2实验类.class;
  40.         //定位单个构造器对象(按照参数,这里定位的是有参的构造器)
  41.         Constructor cons=c.getConstructor(String.class,int.class);
  42.        // Constructor cons=c.getConstructor();//如果获取无参构造器,但因为我设置的是private私有的,权限不足无法获取,便会报错
  43.         System.out.println(cons.getName()+"\t构造器参数个数为:"+cons.getParameterCount()+"个");
  44.         //运行结果:IT2.反射机制_2实验类        构造器参数个数为:2个
  45.     }
  46.     //4、getDeclaredConstructor
  47.     //获取某个构造器:只要你敢写,这里就能拿到,无所谓权限是否可及
  48.     //一般是用这个,什么都可以获取,并且是根据自己需要什么而获取
  49.     @Test
  50.     public void getDeclaredConstructor() throws Exception {
  51.         //获取类对象
  52.         Class c=反射机制_2实验类.class;
  53.         //定位单个构造器对象(按照参数,这里定位的是有参的构造器)
  54.         Constructor cons=c.getDeclaredConstructor(String.class,int.class);
  55.         System.out.println(cons.getName()+"\t构造器参数个数为:"+cons.getParameterCount()+"个");
  56.         //运行结果:IT2.反射机制_2实验类        构造器参数个数为:2个
  57.         //获取类对象
  58.         Class c2=反射机制_2实验类.class;
  59.         //定位单个构造器对象(按照参数定位无参构造器)
  60.         Constructor cons2=c2.getDeclaredConstructor();
  61.         System.out.println(cons2.getName()+"\t构造器参数个数为:"+cons2.getParameterCount()+"个");
  62.         //运行结果:IT2.反射机制_2实验类        构造器参数个数为:0个
  63.     }
  64. }
复制代码
  Class在开发中最常见的用法就是将Class类对象实例化为自定义类的对象,即可通过一个给定的字符串(类的全限定类名)实例化一个本类的对象。将Class对象实例化为本类对象时,可以通过无参构造完成,也可以通过有参构造完成。 
  创建对象:
  1. import org.junit.Test;
  2. import java.lang.reflect.Constructor;
  3. //反射可以破坏封装性,私有的也可以执行了
  4. public class 反射机制_2创建对象 {
  5.     @Test
  6.     public void getDeclaredConstructor() throws Exception {
  7.         //获取类对象
  8.         Class c=反射机制_2实验类.class;
  9.         //定位单个构造器对象(按照参数,这里定位的是有参的构造器)
  10.         Constructor cons=c.getDeclaredConstructor(String.class,int.class);
  11.         System.out.println(cons.getName()+"\t构造器参数个数为:"+cons.getParameterCount()+"个");
  12.         反射机制_2实验类 s1= (反射机制_2实验类) cons.newInstance("狗蛋",18);
  13.         System.out.println(s1);
  14.         System.out.println();
  15.         //获取类对象
  16.         Class c2=反射机制_2实验类.class;
  17.         //定位单个构造器对象(按照参数定位无参构造器)
  18.         Constructor cons2=c2.getDeclaredConstructor();
  19.         System.out.println(cons2.getName()+"\t构造器参数个数为:"+cons2.getParameterCount()+"个");
  20.         //如果遇到了私有的构造器,可以暴力反射
  21.         cons2.setAccessible(true);//权限打开(只是这一次有效,并不是一直打开)
  22.         反射机制_2实验类 s2= (反射机制_2实验类) cons2.newInstance();
  23.         System.out.println(s2);
  24.         //运行结果:
  25.         //IT2.反射机制_2实验类        构造器参数个数为:2个
  26.         //有参构造器执行!
  27.         //反射机制_2实验类{name='狗蛋', age=18}
  28.         //
  29.         //IT2.反射机制_2实验类        构造器参数个数为:0个
  30.         //无参构造器执行!
  31.         //反射机制_2实验类{name='null', age=0}
  32.     }
  33. }
复制代码
  使用反射技术获取成员变量对象并使用

  实验类:
  1. public class 反射机制_2实验类2 {
  2.     private String name;
  3.     private int age;
  4.     public static String schoolName;
  5.     public static final String Name="遇安";
  6.     public 反射机制_2实验类2() {
  7.         System.out.println("无参构造器执行!");
  8.     }
  9.     public 反射机制_2实验类2(String name, int age) {
  10.         System.out.println("有参构造器执行!");
  11.         this.name = name;
  12.         this.age = age;
  13.     }
  14.     public String getName() {
  15.         return name;
  16.     }
  17.     public void setName(String name) {
  18.         this.name = name;
  19.     }
  20.     public int getAge() {
  21.         return age;
  22.     }
  23.     public void setAge(int age) {
  24.         this.age = age;
  25.     }
  26.     public static String getSchoolName() {
  27.         return schoolName;
  28.     }
  29.     public static void setSchoolName(String schoolName) {
  30.         反射机制_2实验类2.schoolName = schoolName;
  31.     }
  32.     @Override
  33.     public String toString() {
  34.         return "反射机制_2实验类2{" +
  35.                 "name='" + name + '\'' +
  36.                 ", age=" + age +
  37.                 '}';
  38.     }
  39. }
复制代码
   获取成员变量:
  在反射操作中可以获取一个类中的全部属性,但是类中的属性包括两部分,即从父类继承的属性和本类定义的属性。因此,在获取类的属性时也有以下两种不同的方式:
  1、获取实现的接口或父类中的公共属性:public Field [] getFields throws SecurityException
  2、获取本类中的全部属性:public Field [] getDeclaredFields throws Exception
  上述两种方法返回的都是Field数组,每一个Field对象表示类中的一个属性。如果要获取属性中的详细信息,就需要调用Field类的方法。
  1. import org.junit.Test;
  2. import java.lang.reflect.Field;
  3. public class 反射机制_2获取成员变量 {
  4.     //1、获取全部的成员变量
  5.   //  Field[] getDeclaredFields
  6.     //获得所有的成员变量对应的Field对象,只要申明了就可以得到
  7.     @Test
  8.     public void getDeclaredFields(){
  9.         //定位Class对象
  10.         Class c=反射机制_2实验类2.class;
  11.         //定位全部成员变量
  12.         Field [] fields=c.getDeclaredFields();
  13.         //遍历获取,常量也会被当做成员变量
  14.         for (Field field : fields) {
  15.             System.out.println(field.getName()+"的类型是:"+field.getType());
  16.         }
  17.     }
  18.     //2、获取某个成员变量对象
  19.     //Field getDeclaredField(String name)
  20.     @Test
  21.     public void getDeclaredField() throws Exception {
  22.         //定位Class对象
  23.         Class c=反射机制_2实验类2.class;
  24.         //根据名称定位某个成员变量
  25.         Field f=c.getDeclaredField("age");
  26.         System.out.println(f);
  27.         System.out.println(f.getName()+"的类型是:"+f.getType());
  28.     }
  29. }
复制代码
  运行结果:
  Test1、
  name的类型是:class java.lang.String
age的类型是:int
schoolName的类型是:class java.lang.String
COUNTTRY的类型是:class java.lang.String 
  Test2、
  private int IT2.反射机制_2实验类2.age
age的类型是:int
     获取了成员变量有什么用呢?
  1. import org.junit.Test;
  2. import java.lang.reflect.Field;
  3. public class 反射机制_2获取成员变量 {
  4.     //获取了成员变量有什么用呢?
  5.     @Test
  6.     public void demo() throws Exception {
  7.         //反射第一步获取Class对象
  8.         Class c=反射机制_2实验类2.class;
  9.         //提取某个成员变量
  10.         Field f=c.getDeclaredField("age");
  11.         f.setAccessible(true);//因为我的age成员变量是用private修饰的,所以需要暴力打开权限
  12.         //作用一:赋值
  13.         反射机制_2实验类2 s=new 反射机制_2实验类2();
  14.         f.set(s,18);//s.setAge(18);
  15.         System.out.println(s);
  16.         //运行结果:
  17.         // 无参构造器执行!
  18.         //反射机制_2实验类2{name='null', age=18}这里可以看出,成员变量被赋值成功
  19.         //作用二:取值
  20.         int age = (int) f.get(s);
  21.         System.out.println(age);//18
  22.     }
  23. }
复制代码
  使用反射技术获取方法对象并使用

  实验类:
  1. public class 反射机制_2实验类3 {
  2.     private String name;
  3.     public 反射机制_2实验类3() {
  4.     }
  5.     public 反射机制_2实验类3(String name) {
  6.         this.name = name;
  7.     }
  8.     public void run(){
  9.         System.out.println("跑起来了。。");
  10.     }
  11.     private void eat(){
  12.         System.out.println("累了,该吃饭了。。");
  13.     }
  14.     private String eat(String name){
  15.         System.out.println("那就浅吃一下"+name+"吧");
  16.         return "针不戳";
  17.     }
  18.     public static void ind(){
  19.         System.out.println("欢迎来到遇安的博客!");
  20.     }
  21.     public String getName() {
  22.         return name;
  23.     }
  24.     public void setName(String name) {
  25.         this.name = name;
  26.     }
  27. }
复制代码
   获取成员方法:
  1. import org.junit.Test;
  2. import java.lang.reflect.Method;
  3. public class 反射机制_2获取成员方法 {
  4.     //获得类中的所有成员方法对象
  5.     @Test
  6.     public void getDeclaredMethods(){
  7.         //获取类对象
  8.         Class c=反射机制_2实验类3.class;
  9.         //提取全部方法,包括私有的
  10.         Method [] methods=c.getDeclaredMethods();
  11.         //遍历全部方法
  12.         for (Method method : methods) {
  13.             System.out.println(method.getName()+"返回值类型:"+method.getReturnType()+"参数个数:"+method.getParameterCount());
  14.         }
  15.     }
  16.     //提取某个方法对象
  17.     @Test
  18.     public void getDeclaredMethod() throws Exception {
  19.         //获取类对象
  20.         Class c=反射机制_2实验类3.class;
  21.         //提取单个方法对象
  22.         Method m1=c.getDeclaredMethod("eat");
  23.         Method m2=c.getDeclaredMethod("eat",String.class);
  24.         //暴力打开权限
  25.         m1.setAccessible(true);
  26.         m2.setAccessible(true);
  27.         //触发方法的执行
  28.         反射机制_2实验类3 s=new 反射机制_2实验类3();
  29.         //注意:如果方法是没有结果返回的,那么返回的是Null
  30.         Object result =m1.invoke(s);
  31.         System.out.println(result);
  32.         Object result2=m2.invoke(s,"海鲜大餐");
  33.         System.out.println(result2);
  34.     }
  35. }
复制代码
  运行结果:
  累了,该吃饭了。。
null
那就浅吃一下海鲜大餐吧
针不戳

来源:https://blog.csdn.net/qq_62731133/article/details/125089941
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表