这样和妻子解释:Java动态代理机制详解(JDK和CGLIB

class文件简介及加载Java编译器编译好Java文件之后 , 产生.class 文件在磁盘中 。 这种class文件是二进制文件 , 内容是只有JVM虚拟机能够识别的机器码 。 JVM虚拟机读取字节码文件 , 取出二进制数据 , 加载到内存中 , 解析.class 文件内的信息 , 生成对应的 Class对象:
这样和妻子解释:Java动态代理机制详解(JDK和CGLIB文章插图
class字节码文件是根据JVM虚拟机规范中规定的字节码组织规则生成的、具体class文件是怎样组织类信息的
下面通过一段代码演示手动加载 class文件字节码到系统内 , 转换成class对象 , 然后再实例化的过程:
a. 定义一个 Programmer类:
package samples;/*** 程序猿类* @author louluan*/public class Programmer {public void code(){System.out.println("I'm a Programmer,Just Coding.....");}}b. 自定义一个类加载器:
package samples;/*** 自定义一个类加载器 , 用于将字节码转换为class对象* @author louluan*/public class MyClassLoader extends ClassLoader {public Class defineMyClass( byte[] b, int off, int len){return super.defineClass(b, off, len);}}c. 然后编译成Programmer.class文件 , 在程序中读取字节码 , 然后转换成相应的class对象 , 再实例化:
package samples;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.net.URL;public class MyTest {public static void main(String[] args) throws IOException {//读取本地的class文件内的字节码 , 转换成字节码数组File file = new File(".");InputStreaminput = new FileInputStream(file.getCanonicalPath()+"\\bin\\samples\\Programmer.class");byte[] result = new byte[1024];int count = input.read(result);// 使用自定义的类加载器将 byte字节码数组转换为对应的class对象MyClassLoader loader = new MyClassLoader();Class clazz = loader.defineMyClass( result, 0, count);//测试加载是否成功 , 打印class 对象的名称System.out.println(clazz.getCanonicalName());//实例化一个Programmer对象Object o= clazz.newInstance();try {//调用Programmer的code方法clazz.getMethod("code", null).invoke(o, null);} catch (IllegalArgumentException | InvocationTargetException| NoSuchMethodException | SecurityException e) {e.printStackTrace();}}}以上代码演示了 , 通过字节码加载成class 对象的能力 , 下面看一下在代码中如何生成class文件的字节码 。
在运行期的代码中生成二进制字节码
由于JVM通过字节码的二进制信息加载类的 , 那么 , 如果我们在运行期系统中 , 遵循Java编译系统组织.class文件的格式和结构 , 生成相应的二进制数据 , 然后再把这个二进制数据加载转换成对应的类 , 这样 , 就完成了在代码中 , 动态创建一个类的能力了 。
这样和妻子解释:Java动态代理机制详解(JDK和CGLIB文章插图
在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码 。 当前有很多开源框架可以完成这些功能 , 如ASM , Javassist 。
Java字节码生成开源框架介绍--ASM:
ASM 是一个 Java 字节码操控框架 。 它能够以二进制形式修改已有类或者动态生成类 。 ASM 可以直接产生二进制 class 文件 , 也可以在类被加载入 Java 虚拟机之前动态改变类行为 。 ASM 从类文件中读入信息后 , 能够改变类行为 , 分析类信息 , 甚至能够根据用户要求生成新类 。