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及以前的版本