技术上可行的方式
生成源码文件 -> 编译源码 -> 加载类
方式1:javac 编译
可以用 ProcessBuilder 这个类启动 javac 进程,编译源码文件
方式2:Java Compiler API 编译
JDK中的 Java Compiler API 提供了与 javac 对等的编译能力。(示例:InMemoryJavaCompiler)
直接生成字节码 -> 加载类
一般通过字节码操作工具和类库来更改Java Class的字节码。
流行的工具有 ASM、Javassist、cglib、Byte Buddy 等。
很多工具/框架中的动态代理实现中就有用到这些工具。如,Spring框架内置了 cglib
字节码 -> Class
将字节码转换为 Class 发生在类加载过程中(《Java类加载》)。
可通过 ClassLoader.defineClass 方法将字节码转换成Class对象。
或者使用JDK中其它对等的方法(不同版本的JDK会略有不同)。
public abstract class ClassLoader { protected final Class<?> defineClass( String name, byte[] b, int off, int len, ProtectionDomain protectionDomain); protected final Class<?> defineClass( String name, java.nio.ByteBuffer b, ProtectionDomain protectionDomain); static native Class<?> defineClass1( ClassLoader loader, String name, byte[] b, int off, int len, ProtectionDomain pd, String source); static native Class<?> defineClass2( ClassLoader loader, String name, java.nio.ByteBuffer b, int off, int len, ProtectionDomain pd, String source); ... }
操作字节码
JDK 动态代理实现方式
JDK动态代理实现的方式是比较hack的,需要了解JVM指令,偏移地址的处理也比较繁琐。
从 ProxyGenerator 类源码可以看出这种方式的使用门槛非常高,不适合普通开发场景。
更抽象方便的类库(ASM等)
JDK内部集成了ASM类库。如,命名空间 jdk.internal.org.objectweb.asm 下的 ClassWriter 类提供了一组用于生成字节码的方法。
public class ClassWriter extends ClassVisitor { // 构建 Class 签名(指定Java版本、访问权限、名称、父类、实现接口等) public final void visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces); // 构建方法 public final MethodVisitor visitMethod( final int access, final String name, final String descriptor, final String signature, final String[] exceptions); // 结束字节码生成 public final void visitEnd(); // 输出字节码,用于前述的 ClassLoader 载入该新建的类 public byte[] toByteArray(); ... } public abstract class MethodVisitor { // 构建方法内部代码 public void visitCode(); ... }
ASM中的 Visitor 模式
在生成/修改字节码的大多数场景中,都是依赖特定结构,修改或新增 方法、变量、类型等。
而Visitor模式的优势就是将算法和对象结构解耦,所以ASM API广泛使用了该模式。
字节码操作技术的使用场景
大多数业务不会直接使用字节码操作技术,但它是很多工具和底层框架必不可少的部分。
Mock 框架、ORM 框架、IOC 容器、Profiler或运行时诊断工具、形式化代码生成工具 等都会用到字节码操作技术。
在一些资源消耗统计的场景中也经常出现字节码操作技术的身影。
如,为了统计某些方法调用的网络通信的消耗,我们可以通过 JavaAgent + 字节码操作技术 来改变相关类,植入统计相关数据的代码。
这种方式不会侵入原业务代码,比AOP的方式更干净。而且不开启统计功能时,是零开销。
相关推荐
根据提供的标题“Java语言程序设计-进阶篇(原书第8版)”,我们可以推测这本书主要聚焦于Java编程语言的高级应用与实践。虽然描述部分为空白,但是结合标题和标签,可以推断出该书内容涉及Java语言的深层次理解和实际...
在Java进阶篇中,会详细介绍List、Set、Map等集合类型的使用场景、性能特点及其提供的各种操作方法。 3. 泛型编程:泛型是Java SE 5版本中引入的一个重要特性,它允许在编译时提供类型安全检查,同时避免了类型转换...
标签“Java 进阶篇 第8版”进一步印证了这本书的定位,即作为Java学习者的进阶指南,并且已经更新到最新版,这可能意味着书中内容与Java的最新版本——截至本知识生成时,Java 16——同步,包含了最新的API和语言...
由于提供的【部分内容】重复且无效,无法从中提取有效知识点,所以我将基于标题和描述来生成关于Java语言程序设计进阶篇的相关知识点。 Java是一种高级的面向对象编程语言,它以其平台无关性、安全性、稳定性和性能...
- **反射**:Class类、Field类、Method类等的使用,实现运行时动态获取类的信息并进行操作的能力。 #### 6. Lambda表达式与Stream API - **Lambda表达式**:简化函数式接口的实现方式,提高代码的可读性和简洁性。...
GTK,全称GIMP Toolkit,是一个用于创建图形用户界面(GUI)的开源工具包,广泛应用于Linux和其他类Unix系统。这个“gtk学习代码-进阶版”压缩包很可能是为那些已经对GTK基础有一定了解,想要深入研究和提升GTK编程...
接下来是“Java进阶”部分,这部分将深入探讨更多高级特性: 1. **多线程**:Java提供的Thread类和Runnable接口,线程同步机制(synchronized关键字、wait/notify、Lock锁)以及并发工具类。 2. **网络编程**:套...
- 使用JNI的开发流程通常包括编写Java代码、生成JNI头文件、编写本地代码实现、编译本地代码并生成库文件、最后在Java中加载库文件并调用本地方法。 总之,Java JNI编程进阶涉及到性能优化、本地系统接口调用和...
- 反射允许在运行时检查类的信息(如方法、字段、构造器),动态创建对象和调用方法。 【关于String】 - `String`是不可变对象,意味着一旦创建,其内容不能改变。如在代码中`s1=s1 + s2;`会创建一个新的`String`...
* 枚举是一种特殊的类,它继承自 java.lang.Enum 类。 * 枚举中的常量是public、static、final 的。 * 枚举可以使用toString()方法来获取枚举的名称。 * 枚举可以使用values()方法来获取枚举的所有常量。 * 枚举可以...
`java.util.concurrent.ForkJoinPool`和`java.util.concurrent.RecursiveTask`是其核心类。 7. **非阻塞堆栈跟踪(Non-blocking Stack Traces)** 当线程处于等待状态时,Java 7可以生成不包含阻塞信息的堆栈跟踪...
Java大神进阶之路是一份针对Java开发者进阶提升的学习指南,详细描述了从编程基础到Java语言本身的精通,再到数据库以及Java Web核心技术的掌握,以及每个阶段所需要学习和掌握的知识点。文中特别强调了数据结构和...
"Java进阶基础.zip"这个压缩包很可能包含了帮助开发者深化Java理解的材料,涵盖了从核心概念到高级特性的各个方面。以下是一些可能涵盖的Java进阶基础知识: 1. **异常处理**:Java的异常处理机制是其强项之一,...
7. **反射**:反射机制允许在运行时检查类的信息并动态调用方法。在某些场景下,如插件系统或框架开发,反射的应用非常关键。 8. **注解(Annotation)**:注解提供了元数据,可以用于代码的编译、运行时验证和工具...
总的来说,这个"JAVA项目---个人博客"是一个综合性的学习资源,涵盖了Web开发的基础和进阶知识,包括服务器端编程(JSP和Servlet)、前端交互(JavaScript)、页面组件复用(iframe)以及安全性措施(验证码)。...
3. **Servlet与JSP技术**:Servlet是运行在服务器端的小型Java程序,负责接收客户端请求,执行业务逻辑,生成动态内容并返回响应。JSP则是将Java代码嵌入到HTML页面中的技术,它允许开发者将动态内容直接嵌入到页面...
学习Java时,首先需要安装Java Development Kit(JDK),它包含了编译和运行Java程序所需的工具,如`javac.exe`(编译器)和`java.exe`(解释器)。安装JDK后,还需要设置环境变量PATH,以便在命令行中可以全局访问...
3. **反射**:反射允许程序在运行时检查和操作类、接口、字段和方法,这是Java动态性的一个重要体现。学习反射可以理解如何在运行时创建对象、调用方法和访问私有成员。 4. **注解(Annotation)**:注解是一种元...
2. **JSP**:Java Server Pages是用于动态生成HTML的工具,它将Java代码嵌入到HTML中,使得网页具有更强的动态性。书中将涵盖JSP指令、脚本元素、EL(表达式语言)和JSTL(JavaServer Pages Standard Tag Library)...