• Java 反射 —— 运行时的类型信息


    1. 反射机制的由来

    RTTI 机制可以告知某个对象的确切类型,但有一个前提,该类型在编译时必须已知(编译器在编译时打开和检查 .class 文件以获取类型信息)。似乎是个很宽松的限制,但假如你获取了一个指向并不在你的程序空间的对象的引用,也即编译期间无法获知该对象所属的类,等到程序真正运行起来时,才有可能。比如,在网络连接中获取了一串(事先不被预知)的字节,并被告知这些字节代表着一个类。然而该类在为你的程序生成代码之后很久才出现,那么如何在编写代码时,使用这样的类呢?

    • RTTI 与 反射的区别:
      • RTTI 需要在编译时打开和检查 .class 文件
      • 对于反射机制,.class 文件在编译时是无法获取的,所以是在运行时打开和检查 .class 文件

    2. reflect 类库

    Class 类库与 java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了如下三种类(每个类均实现了 Member 接口(interface Member)):

    • Field:成员变量;
    • Method:成员函数;
    • Constructor:构造器;

    Java 的反射机制能获取未知类的全部成员,包括构造函数。

    3. 一个实例

    • Car 类:

      package reflect;
      
      public class Car {
          private String brand;
          private String color;
          private int maxSpeed;
          public Car() {}
          public Car(String brand, String color, int maxSpeed) {
              this.brand = brand;
              this.color = color;
              this.maxSpeed = maxSpeed;
          }
          // getters, setters 方法
      }

      为了体现 java 反射机制的威力,我们不采用直接 new 的方式(有时候,比如远程过程调用 RPC,我们无法确切地知道其构造函数的参数列表)

    • ReflectTest

      package reflect;
      
      import java.lang.reflect.Constructor;
      import java.lang.reflect.Method;
      
      public class ReflectTest {
      
          public static Car initByDefaultConst() throws Throwable{
              ClassLoader loader = Thread.currentThread().getContextClassLoader();
              Class<?> clazz = loader.loadClass("reflect.Car");
              Constructor<?> cons = clazz.getDeclaredConstructor((Class[])null);
              Car car = (Car)cons.newInstance();
      
      
              Method setBrand = clazz.getMethod("setBrand", String.class);
              setBrand.invoke(car, "红旗CA72");
              Method setColor = clazz.getMethod("setColor", String.class);
              setColor.invoke(car, "黑色");
              Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
              setMaxSpeed.invoke(car, 100);
              return car;
          }
      
          public static void main(String[] args) throws Throwable {
      
              Car car = initByDefaultConst();
              System.out.println(car);
      
          }
      
      }
  • 相关阅读:
    从json中获取自己想要的属性
    对称加密解密
    springboot 读取resource目录下的文件
    安装nginx 配置了ssl 启动报错
    复利计算--4.0 单元测试之JAVA版-软件工程
    《构建之法》前三章读后感
    单利 复利计算器程序1.0 2.0 3.0 [ 合 ] 之 WEB
    操作系统 实验一 命令解释程序的编写
    单利 复利计算器程序1.0 2.0 3.0 [ 合 ] 之 C语言
    统计实验数据 总结实验结果
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9421196.html
Copyright © 2020-2023  润新知