博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 之反射机制
阅读量:7041 次
发布时间:2019-06-28

本文共 2443 字,大约阅读时间需要 8 分钟。

java 语言的反射机制

- 在运行状态中,对于任意一个类 (class 文件),都能够知道这个类的所有属性和方法;- 能动态获取类中的信息,也可以理解为对类(字节码文件)的解剖

1222878-20170914223509516-284337094.png

描述字节码文件的类

1222878-20170914223525750-421513519.png

与反射相关的三个对象

- Constuctor : 将构造函数封装成对象- Field : 将字段封装成对象- Method : 将一般方法封装成对象

获取字节码对象的三种方式

  1. Object 类中的 getClass() 方法
    • 想要用这种方式获取, 必须要明确具体的类, 并且需要创建对象
  2. 任何数据类型都具备一个静态的属性, 即通过.class来获取其对应的 Class 对象
    • 相对简单, 但是还是要明确用到类中的静态成员
  3. 只有通过给定的类的字符串名称就可以获取该类, 此方法更为扩展
    • 可以使用 Class 类中的 forName() 方法完成
    • 这种方式只要有名称即可, 更为方便, 扩展性更强

获取 Class 中的构造函数

// 早期: 使用 new 创建对象, 先根据被 new 的类的名称找寻该类的字节码文件, 并加载进内存,//      然后创建该字节码文件对象, 接着创建该字节码文件的对应的 Person 对象    cn.itcast.bean.Person p = new cn.itcast.bean.Person();// 现在: 使用反射机制    String name = "cn.itcast.bean.Person";// 找寻该名称对应的类文件, 并加载进内存, 产生 Class 对象    Class clazz = Class.forName(name);// 如何产生该类的对象呢?      Object obj = clazz.newInstance();  // 调用空参的构造函数/* * 当获取指定名称对应类所体现的对象时, * 该类初始化不使用空参数构造函数该怎么办呢? * 构造函数带有了参数,就相当于指定了类中的某一个构造函数. * 既然通过指定的构造函数进行对象的初始化, * 所以应该先获取到该构造函数, 而这只需要通过字节码文件对象即可完成 * 该方法有: *     getConstructors();  获取所有公共的构造函数 *     getDeclaredConstructors();  获取所有构造函数.(包含公共, 保护, 默认访问和私有构造方法) *     getConstructor(Class
... parametreTypes); */ // 获取指定的构造函数对象// 任何数据类型都具有一个静态的属性, .class, 获取 Class 对象 Constructor constructor = clazz.getConstructor(String.class,int.class);// 通过该构造器对象 newInstance 方法进行对象的初始化 Object obj = constructor.newInstance("张三",18);

获取 Class 中的字段

String name = "cn.itcast.bean.Person";// 找寻该名称对应的类文件, 并加载进内存, 产生 Class 对象    Class clazz = Class.forName(name);// 获取相应的字段    // Field field = clazz.getField("age");   只能获取公有的    Field field = clazz.getdeclaredField("age"); // 只获取本类, 但包含私有    // 对私有字段的方位取消权限检查, 暴力访问        field.setAccessible(true);// 因为 Person p = new Person();//  设置 p 对象的年龄: p.age = 30;// 所以反射机制中获取(设置)字段的值,需要指定对象    Object obj = clazz.newInstance();    // 设置值        field.set(obj,89);    // 获取值    Object o = field.get(obj);

获取 Class 中的方法

// 找寻该名称对应的类文件, 并加载进内存, 产生 Class 对象    Class clazz = Class.forName( "cn.itcast.bean.Person");    Method[] methods = clazz.getMethods();  // 获取的都是公有的方法    methods = clazz.getDeclaredMethods();  // 只获取本类中所有方法, 包含私有// 获取指定名称的公有方法, 需要指定方法名称和参数列表    Method method = clazz.getMethod("show", null);  // 获取空参数的一般方法// 创建对象    Object obj = clazz.newInstance();// 一般方法的运行, 需要指定对象和参数列表    method.invoke(obj,null);// 获取有参的一般方法    Method method = clazz.getMethod("paramMethod", String.class, int.class);// 创建对象    Object obj3 = clazz.newInstance();// 一般方法运行    method.invoke(obj,"小强",24);

参考资料

转载于:https://www.cnblogs.com/linkworld/p/7523608.html

你可能感兴趣的文章
paper 135:关于C#泛型的知识点
查看>>
第二十四条:消除非受检警告
查看>>
给阅读的网页作标记
查看>>
vue条件渲染
查看>>
转 MySQL数据库基础
查看>>
Oracle dblink创建
查看>>
python04 while循环
查看>>
web 开发之酷炫--- 酷炫展示
查看>>
ubuntu 解压命令全部
查看>>
Chrome教程(一)NetWork面板分析网络请求
查看>>
第十八回  基础才是重中之重~开发人员应学会用throw
查看>>
Rosenblatt's perceptron
查看>>
1570:基础练习 分解质因数
查看>>
判断ie浏览器7、8、9三个版本
查看>>
GDUFE ACM-1124
查看>>
Schwarz积分公式
查看>>
工作中常用的 Linux 命令
查看>>
English Corner
查看>>
(最短路 SPFA)Invitation Cards -- poj -- 1511
查看>>
两数相加LeetCode
查看>>