Java 字节码操作和 Java 反射 API?
Java Bytecode Manipulation and Java reflection API?
我最近遇到了术语 "Bytecode manipulation"(为什么要研究这个,我在使用 Hibernate 的应用程序中查看日志时偶然看到了字节码提供程序)。我也(有点)了解 Java 反射 API.
这两个概念相似吗?它们之间有什么区别?什么时候使用哪个?
反射 API 允许您访问有关已加载到 JVM 的 classes 的成员(字段、方法、接口、e.t.c)的信息。这个 API 不允许修改 class 的行为,除了一些基本的东西,比如调用私有方法。
反射 API 适用的一些示例
- 依赖注入框架可以将依赖设置到所有者对象的私有字段。
- 您可以使用反射为您的 class 生成 equals/hashCode/toString 方法,而无需在添加新字段或删除现有字段时枚举所有字段并修改这些方法
- 再次使用 Relfection Api 将您的 class 序列化为 JSON/XML/Yaml 或任何其他格式,而无需枚举所有字段
相反,字节码操作允许您对磁盘上的某些 .class 文件或已经使用 class 加载到 JVM 的 classes 进行任何更改=40=]代理API
字节码操作适用的几个示例:
- 来自 Java 标准库的代理仅支持代理接口;字节码操作允许您添加关于 class 方法的建议
- 用于单元测试的模拟框架允许替换私有静态方法的 return 值 - 它是使用字节码操作实现的
- 分析器用时间记录代码包装每个方法
这是它的外观
private void foo() {
long start = System.currentTimeMillis(); // inserted by bytecode manipulation
Profiler.enterMethod("foo"); // inserted by bytecode manipulation
try { // inserted by bytecode manipulation
// original method code
} finally { // inserted by bytecode manipulation
Profiler.exitMethod("foo", System.currentTimeMillis() - start); // inserted by bytecode manipulation
} // inserted by bytecode manipulation
}
我最近遇到了术语 "Bytecode manipulation"(为什么要研究这个,我在使用 Hibernate 的应用程序中查看日志时偶然看到了字节码提供程序)。我也(有点)了解 Java 反射 API.
这两个概念相似吗?它们之间有什么区别?什么时候使用哪个?
反射 API 允许您访问有关已加载到 JVM 的 classes 的成员(字段、方法、接口、e.t.c)的信息。这个 API 不允许修改 class 的行为,除了一些基本的东西,比如调用私有方法。
反射 API 适用的一些示例
- 依赖注入框架可以将依赖设置到所有者对象的私有字段。
- 您可以使用反射为您的 class 生成 equals/hashCode/toString 方法,而无需在添加新字段或删除现有字段时枚举所有字段并修改这些方法
- 再次使用 Relfection Api 将您的 class 序列化为 JSON/XML/Yaml 或任何其他格式,而无需枚举所有字段
相反,字节码操作允许您对磁盘上的某些 .class 文件或已经使用 class 加载到 JVM 的 classes 进行任何更改=40=]代理API
字节码操作适用的几个示例:
- 来自 Java 标准库的代理仅支持代理接口;字节码操作允许您添加关于 class 方法的建议
- 用于单元测试的模拟框架允许替换私有静态方法的 return 值 - 它是使用字节码操作实现的
- 分析器用时间记录代码包装每个方法
这是它的外观
private void foo() {
long start = System.currentTimeMillis(); // inserted by bytecode manipulation
Profiler.enterMethod("foo"); // inserted by bytecode manipulation
try { // inserted by bytecode manipulation
// original method code
} finally { // inserted by bytecode manipulation
Profiler.exitMethod("foo", System.currentTimeMillis() - start); // inserted by bytecode manipulation
} // inserted by bytecode manipulation
}