关键词搜索

源码搜索 ×
×

一篇文章带你搞定 Java 中反射的应用(取得类的结构)

发布2020-02-21浏览557次

详情内容

框架:半成品软件,可以在框架的基础上进行软件开发,简化编码

反射:将类的各个组成部分封装为其他对象,这就是反射机制

好处:
	* 可以在程序运行过程中,操作这些对象。
	* 可以解耦,提高程序的可扩展性。

    一、基本概念

    反射机制中,还可以通过反射得到一个类的完整结构,这就需要使用 java.lang.reflect 包中的以下几个类:

    Constructor:表示类中的构造方法
    Field:表示类中的属性
    Method:表示类中的方法
    

      这三个类都是 AccessibleObject 类的子类:
      在这里插入图片描述

      interface China{
          public static final String NATIONAL = "China";
          public static final String AUTHOR = "Java";
          public void sayChina();//定义无参的抽象方法
          public String sayHello(String name,int age);//定义有参的抽象方法
      }
      class Person implements China{
          private String name;
          private int age;
          public Person(){
          }
          public Person(String name){//声明有一个参数的构造方法
              this.name = name;
          }
          public Person(String name,int age){
              this(name);
              this.setAge(age);
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public void sayChina() {
              System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL);
          }
      
          @Override
          public String sayHello(String name, int age) {
              return name + "你好!我今年" + age + "岁了!";
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41

      二、取得所实现的全部接口

      要取得一个类所实现的全部接口,必须使用 Class 类中的 getInterfaces() 方法,该方法定义:

      public Class[] getInterfaces()
      
      • 1

      getInterfaces() 方法返回一个 Class 类的对象数组,之后直接利用 Class 类中的 getName() 方法输出即可。

      public class Root{
          public static void main(String[] args) {
              Class<?> c1 = null;//声明 Class对象
              try{
                  c1 = Class.forName("Person");
              }catch (ClassNotFoundException e){
                  e.printStackTrace();
              }
              Class<?> c[] = c1.getInterfaces();//取得实现的全部接口
              for (int i=0;i<c.length;i++){
                  System.out.println("实现的接口名称:" + c[i].getName());//输出接口名称
              }
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      因为接口是类的特殊形式,而且一个类可以实现多个接口,所以此时以 Class 数组的形式将全部的接口对象返回,并利用循环的方式将内容依次输出

      三、取得父类

      一个类可以实现多个接口,但是只能继承一个父类,所以要想取得一个类的父类,可以直接使用 Class 类中的 getSuperclass() 方法,该方法定义:

      public Class<? super T> getSuperclass()
      
      • 1

      getSuperclass() 方法返回的是 Class 实例,和之前得到的接口一样,可以通过 getName() 方法取得名称。

      public class Test{
          public static void main(String[] args) {
              Class<?> c1 = null;
              try {
                  c1 = Class.forName("Person");
              }catch (ClassNotFoundException e){
                  e.printStackTrace();
              }
              Class<?> c2 = c1.getSuperclass();//取得父类信息
              System.out.println("父类名称:" + c2.getName());
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      在这里插入图片描述
      Person 类在编写时没有明确地继承一个父类,所以默认继承 Object 类

      四、取得全部构造方法

      要取得一个类中的全部构造方法,必须使用 Class 类中的 getConstructors() 方法。

      1. 取得 Person 类的全部构造方法
      import java.lang.reflect.Constructor;
      
      public class Test{
          public static void main(String[] args) {
              Class<?> c1 = null;
              try {
                  c1 = Class.forName("Person");
              }catch (ClassNotFoundException e){
                  e.printStackTrace();
              }
              Constructor<?> con[] = c1.getConstructors();//得到全部构造方法
              for (int i=0;i<con.length;i++){
                  System.out.println("构造方法:" + con[i]);
              }
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      1. 取得一个类的全部构造方法
      import java.lang.reflect.Constructor;
      import java.lang.reflect.Modifier;
      
      public class Test{
          public static void main(String[] args) {
              Class<?> c1 = null;
              try {
                  c1 = Class.forName("Person");
              }catch (ClassNotFoundException e){
                  e.printStackTrace();
              }
              Constructor<?> con[] = c1.getConstructors();//得到全部构造方法
              for (int i=0;i<con.length;i++){
                  Class<?> p[] = con[i].getParameterTypes();//列出构造中的参数类型
                  System.out.print("构造方法:");
                  int mo = con[i].getModifiers();//取出权限
                  System.out.print(Modifier.toString(mo) + " ");//还原权限
                  System.out.print(con[i].getName());//输出构造方法名称
                  System.out.print("(");
                  for (int j=0;j<p.length;j++){
                      System.out.print(p[j].getName() + " arg" + i);
                      if (j<p.length-1){//打印参数类型,判断是否要输出“,”
                          System.out.print(",");
                      }
                  }
                  System.out.println("){}");
              }
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29

      在这里插入图片描述

      五、取得全部方法

      要取得一个类中的全部方法,可以使用 Class 类中的 getMethods() 方法,该方法返回一个 Method 类的对象数组。该方法的常用方法:
      在这里插入图片描述
      在这里插入图片描述
      取得一个类的全部方法定义:

      import java.lang.reflect.Method;
      import java.lang.reflect.Modifier;
      
      public class Test{
          public static void main(String[] args) {
              Class<?> c1 = null;
              try {
                  c1 = Class.forName("Person");
              }catch (ClassNotFoundException e){
                  e.printStackTrace();
              }
              Method m[] = c1.getMethods();//取得全部的方法
              for (int i=0;i<m.length;i++){
                  Class<?> r = m[i].getReturnType();//取出方法的返回值类型
                  Class<?> p[] = m[i].getParameterTypes();//得到全部的参数类型
                  int xx = m[i].getModifiers();//得到方法的修饰符
                  System.out.print(Modifier.toString(xx) + " ");//还原修饰符
                  System.out.print(r.getName() + " ");//得到方法名称
                  System.out.print(m[i].getName());//取得方法名称
                  System.out.print("(");
                  for (int x=0;x<p.length;x++){
                      System.out.print(p[x].getName() + " " + "arg" + x);//输出参数
                      if (x<p.length-1){
                          System.out.print(",");//判断是否输出","
                      }
                  }
                  Class<?> ex[] = m[i].getExceptionTypes();//得到全部的异常抛出
                  if (ex.length>0){
                      System.out.print(") throws ");//输出“) throws”
                  }else {
                      System.out.print(")");
                  }
                  for (int j=0;j<ex.length;j++){
                      System.out.print(ex[j].getName());//输出异常信息
                      if (j<ex.length-1){
                          System.out.print(",");
                      }
                  }
                  System.out.println();
              }
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42

      开发工具就是利用了反射的原理

      六、取得全部属性

      在反射操作中也同样可以取得一个类中的全部属性,有两种不同的操作:

      得到实现的接口或父类中的公共属性:public Field[] getFields() throws SecurityException
      得到本类中的全部属性:public Field[] getDeclareDeclaredFields() throws SecurityException
      
      • 1
      • 2

      上述方法返回的都是 Field 的数组,每一个 Field 对象表示类中的一个属性,而要想取得属性的进一步信息,需要使用:
      在这里插入图片描述
      取得 Person 类中的属性

      import java.lang.reflect.Field;
      import java.lang.reflect.Modifier;
      
      public class Test{
          public static void main(String[] args) {
              Class<?> c1 = null;
              try {
                  c1 = Class.forName("Person");
              }catch (ClassNotFoundException e){
                  e.printStackTrace();
              }
              {//普通代码块
                  Field f[] = c1.getDeclaredFields();//取得本类属性
                  for (int i=0;i<f.length;i++){
                      Class<?> r = f[i].getType();//取得属性的类型
                      int mo = f[i].getModifiers();//得到修饰符数字
                      String priv = Modifier.toString(mo);//取得属性的修饰符
                      System.out.print("本类属性:");
                      System.out.print(priv + " ");//输出修饰符
                      System.out.print(r.getName() + " ");//输出属性类型
                      System.out.print(f[i].getName());//输出属性名称
                      System.out.println(";");//换行
                  }
              }
              System.out.println("===========================");
              {
                  Field f[] = c1.getFields();//取得父类公共属性
                  for (int i=0;i<f.length;i++){
                      Class<?> r = f[i].getType();//取得属性的类型
                      int mo = f[i].getModifiers();//取得修饰符数字
                      String priv = Modifier.toString(mo);//取得属性修饰符
                      System.out.print("公共属性:");
                      System.out.print(priv + " ");//输出修饰符
                      System.out.print(r.getName() + " ");//输出参数类型
                      System.out.print(f[i].getName());//输出属性名称
                      System.out.println(";");
                  }
              }
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40

      相关技术文章

      点击QQ咨询
      开通会员
      返回顶部
      ×
      微信扫码支付
      微信扫码支付
      确定支付下载
      请使用微信描二维码支付
      ×

      提示信息

      ×

      选择支付方式

      • 微信支付
      • 支付宝付款
      确定支付下载