JVM 知识点题目解答之一
因最近一直在学习 JVM,看到 BlueDavy 的一篇文章 JVM知识点题目,于是便激起了我去解答的兴趣。
字节码的加载
1、写一段将目录中指定的.class文件加载到JVM的程序,并通过Class对象获取到完整类名等信息;
对于 ClassLoader 的加载机制、过程及双亲委派模型等这里就不详细介绍了,基本上属于老生长谈的东西了。不过不了解朋友的可以看一下该作者文章:
深入JVM(4):关于ClassLoader的一些知识
先定义一个 DirectoryClassLoader继承 ClassLoader,通过加载指定的目录下的 class 文件,以下贴出该类的主要代码,完整的代码请从附件中下载。
输入结果:
Class: Apple - ClassLoader: it.denger.jvm.classloader.DirectoryClassLoader@3d434234
Class: Banana - ClassLoader: it.denger.jvm.classloader.DirectoryClassLoader@3d434234
Class: it.denger.Pear - ClassLoader: it.denger.jvm.classloader.DirectoryClassLoader@3d434234
Class: java.lang.String - ClassLoader: null
目录结构:
可以看出,以上目录下的"所有" class 文件均已经加载,并且所对应的 ClassLoader 都为 DirectoryClassLoader。唯独 java.lang.String 类的 ClassLoader 为 null,其原因是由于 ClassLoader 的双亲委派模型,因为 String 属于 jre 核心库,已由 BootStrap ClassLoader 加载,而 BootStrap 的加载过程是由 C 实现,所以这里自然就是空了。
其实这题还有另外一个更加简单的方法,就是通过 URLClassLoader 进行加载,示例代码如下:public void testShouldBeLoadStudentNewInstance() {try {Class<?> studentClass = new UserClassGenLoader(new StudentClassGenBuilder()).loadClass("it.denger.jvm.code.bcel.Student");IUser studentUser = (IUser) studentClass.newInstance();assertNotNull(studentUser);assertEquals(studentUser.getClass().getName(), "it.denger.jvm.code.bcel.Student");studentUser.jump();studentUser.run();} catch (Exception e) {fail(e.getMessage());}}}
运行之后显示绿条,并在控制台输出了:
I'm jump....
I'm run....
OK, 至此已经完成本题的所有要求。虽然这里只是简单的实现两个无参、无返回值并且只是 println 输出,但是 BCEL 能做的远远不止这些,理论上来说只要你能手写出的代码基本上都能通过其 API 来动态生成字节码。P.S: 上面代码没写什么注释不过其代码看上去应该比较好懂,有什么可以提出.
~
如果对于以上我个人的分析和理解与你有什么偏差的话,希望能提出一起讨论,另外关于后面两大部分题,现在还在 writing 中,将在近期发出。
进入论坛讨论
