1.反射基础
- 反射:reflection
- 程序可以访问、检测和修改它本身状态或行为的能力,即自描述
和自控制。 - 可以在运行时加载、探知和使用编译期间完全未知的类。
- 给 Java 插上动态语言特性的翅膀,弥补强类型语言的不足。
- java.lang.reflect 包,在 Java 2 时代就有,在 Java 5 得到完善
- 程序可以访问、检测和修改它本身状态或行为的能力,即自描述
反射功能
- 在运行中分析类的能力
- 在运行中查看和操作对象
- 基于反射自由创建对象
- 反射构建出无法直接访问的类
- set 或者 get 到无法访问的成员变量
- 调用不可访问的方法
- 实现通用的数组操作代码
- 类似函数指针的功能
创建对象
- 方法 1:静态编码&编译
1 | A obj1 = new A(); |
- 方法 2:克隆(clone)
1 | public class B implements Cloneable { |
- 方法 3:序列化(serialization)和反序列化(deserialization)
1 | public class C implements Serializable { |
- 方法 4 和 5:反射
1 | public class A { |
2.反射关键类
- Class:类型标识
- JVM 为每个对象都保留其类型标识信息(Runtime Type Identification)
- 三种获取方式
1 | String s1 = "abc"; |
获取详细信息
- getFields()
- 返回本类和所有父类所有的 public 成员变量
- getDeclareFields()
- 返回本类自己定义的成员变量,包括 private 变量,不包括父类变量
1 | A obj = new A(20, "Tom"); |
- getMethods()
- 返回本类和所有父类所有的 public 方法
- getDeclareMethods()
- 返回本类自己定义的方法,包括 private 方法,不包括父类方法
1 | B obj = new B(); |
- getPackage()
- 返回本类所在包
- getModifiers()
- 返回本类前缀修饰符
- getInterfaces()
- 返回本类继承的接口
- getSuperClass()
- 返回本类的父类
1 | Son son = new Son(); |
- getConstructors()
- 返回本类所有的构造函数
1 | D d = new D(); |
- getAnnotations()
- 返回本类的注解
3.反射应用
数据库连接
- JDBC
- Connection,连接到各个不同数据库
1 | try { |
数组扩充器
- 给定一个数组(任意类型),将其长度扩大一倍
- Java 的数组一旦创建,其长度是不再更改的
- 新建一个大数组(相同类型),然后将旧数组的内容拷贝过去
1 | public static void main(String[] args) { |
动态执行方法
- 给定类名、方法名,即可执行
- 加上定时器,即可做定时任务执行
1 | Timer timer = new Timer(); |
Json 和 Java 对象互转
- Json:
{"name":"Jo","email":"a@b.com"}
1 | Gson gson = new Gson(); |
Tomcat 的 Servlet 对象创建
MyBatis 的 OR/M
Spring 的 Bean 容器
org.reflections 包介绍
- Reflection 的增强工具包
- https://github.com/ronmamo/reflections
- Java runtime metadata analysis
- 获取某类的所有子类型
- 获取有特殊 annotation 的类型或者成员变量/方法
- 根据正则表达式获取资源(类/成员变量/方法) • 根据组合条件查询相应的方法
- ……
- https://github.com/ronmamo/reflections
编译器 API
- 对.java 文件即时编译
- 对字符串即时编译
- 监听在编译过程中产生的警告和错误
- 在代码中运行编译器(并非:Runtime 命令行调用 javac 命令)
JavaCompiler
- 自 Java 1.6 推出,位于 javax.tools 包中
- 可用在程序文件中的 Java 编译器接口(代替 javac.exe)
- 在程序中编译 java 文件,产生 class 文件
- run 方法(继承自 java.tools.Tools):较简单。可以编译 java 源文件,生成 class 文件,但不能指定输出路径,监控错误信息, 调用后就在源码所在目录生成 class 文件
1 | JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); |
- getTask 方法:更强大的功能。可以编译 java 源文件,包括在内存中的 java 文件(字符串),生成 class 文件
1 | public static void compileJavaFromString() { |
Java 编译器 API 作用
- Java EE 的 JSP 编译
- 在线编程环境
- 在线程序评判系统(Online Judge 系统)
- 自动化的构建和测试工具
- ……
基于 JavaCompiler 的集成工具
- Janino,http://janino-compiler.github.io/janino
- InMemoryJavaCompile,https://github.com/trung/InMemoryJavaCompiler
- Java-Runtime-Compiler, https://github.com/OpenHFT/Java-Runtime-Compiler
- Apache Commons JCI(Java Compiler Interface), http://commons.apache.org/proper/commons-jci/index.html 适用于 JDK1.5 及以前的版本
Leave a comment