java 语言的反射机制

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

描述字节码文件的类

与反射相关的三个对象

- 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);

**参考资料**

最新文章

  1. Hangfire项目实践分享
  2. Java基本概念(2)J2EE里面的2是什么意思
  3. 设置glassfish开启自动domain
  4. Linux上F上传文件到FTP服务器
  5. python :eval将字符串转换成字典
  6. 简单shell脚本
  7. ETL控件学习之一从数据库导出数据到平面
  8. 一个跨平台的 C++ 内存泄漏检测器
  9. ubuntu安装wine之后进不了系统
  10. MongoDB系列:把mongodb作为windows的服务来启动
  11. 开博近一年的感想 by 程序员小白
  12. window10上登录Oracle时提示ORA-12546:Permission denied
  13. [日常] imap协议读取邮件
  14. [USACO08JAN]牛大赛Cow Contest
  15. fatal: unable to access &#39;https://github.com/open-falcon/falcon-plus.git/&#39;: Peer reports incompatible or unsupported protocol version
  16. Eclipse新建工作空间,复制原有的配置
  17. 56. Merge Intervals (Array; Sort)
  18. WebGL学习笔记七点一
  19. matlab运行过程中出现找不到指定模块问题解决
  20. .pnts点云

热门文章

  1. atitit.词法分析原理&#160;词法分析器 (Lexer)
  2. [css]后台管理系统布局
  3. [css]margin-top重叠
  4. [华为机试练习题]5.IP地址推断有效性
  5. HashMap 内部原理
  6. 基于Java Mina框架的部标jt808服务器设计和开发
  7. VMWare虚拟机端口转发
  8. maven下载、配置和安装
  9. scrapy-redis源代码分析
  10. 本地运行storm时报错