Java 核心技术面试精讲
杨晓峰
前 Oracle 首席工程师
125942 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
Java 核心技术面试精讲
15
15
1.0x
00:00/00:00
登录|注册

第24讲 | 有哪些方法可以在运行时动态生成一个Java类?

实现对某类型资源消耗的统计
字节码操作的应用场景
ASM类库的使用
JDK dynamic proxy的实现逻辑
JDK提供的defineClass方法
类加载过程中的字节码到Class对象的转换
字节码操纵技术的应用场景
利用字节码操纵技术实现动态代理逻辑
字节码和类加载转换
使用字节码操纵工具和类库
生成字节码交给类加载器
利用Java Compiler API
从源码生成
一课一练
知识扩展
考点
方法
动态生成Java类

该思维导图由 AI 生成,仅供参考

在开始今天的学习前,我建议你先复习一下专栏第 6 讲有关动态代理的内容。作为 Java 基础模块中的内容,考虑到不同基础的同学以及一个循序渐进的学习过程,我当时并没有在源码层面介绍动态代理的实现技术,仅进行了相应的技术比较。但是,有了上一讲的类加载的学习基础后,我想是时候该进行深入分析了。
今天我要问你的问题是,有哪些方法可以在运行时动态生成一个 Java 类?

典型回答

我们可以从常见的 Java 类来源分析,通常的开发过程是,开发者编写 Java 代码,调用 javac 编译成 class 文件,然后通过类加载机制载入 JVM,就成为应用运行时可以使用的 Java 类了。
从上面过程得到启发,其中一个直接的方式是从源码入手,可以利用 Java 程序生成一段源码,然后保存到文件等,下面就只需要解决编译问题了。
有一种笨办法,直接用 ProcessBuilder 之类启动 javac 进程,并指定上面生成的文件作为输入,进行编译。最后,再利用类加载器,在运行时加载即可。
前面的方法,本质上还是在当前程序进程之外编译的,那么还有没有不这么 low 的办法呢?
你可以考虑使用 Java Compiler API,这是 JDK 提供的标准 API,里面提供了与 javac 对等的编译器功能,具体请参考java.compiler相关文档。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java动态生成类和字节码操纵技术是在Java编程中常见且重要的技术。通过Java Compiler API和字节码操纵工具,开发者可以在运行时动态生成Java类,并实现对字节码的操作。这些技术在动态代理等场景中得到广泛应用,对于面试准备也具有重要意义。文章从类加载机制、字节码操纵技术和动态代理的实现原理和应用场景进行了深入探讨。通过分析JDK提供的defineClass方法和动态代理的实现逻辑,以及介绍了ASM类库的使用,帮助读者理解了字节码到Java对象的转换过程和动态代码生成的实现过程。此外,文章还探讨了字节码操纵技术在各种框架、工具和应用中的广泛应用,包括Mock框架、ORM框架、IOC容器等。总体而言,本文深入探讨了类加载和字节码操作方面的技术,为读者提供了全面的技术视角和实践应用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(15)

  • 最新
  • 精选
  • 三口先生
    将资源消耗的这个实例,用动态代理的方式创建这个实例动态代理对象,在动态代理的invoke中添加新的需求。开始使用代理对象,不开启则使用原来的方法,因为动态代理是在运行时创建。所以是零消耗。

    作者回复: 不错

    2018-06-30
    67
  • tyson
    可以考虑用javaagent+字节码处理拦截方法进行统计:对httpclient中的方法进行拦截,增加header或者转发等进行统计。开启和关闭只要增加一个javaagent启动参数就行

    作者回复: 是的,我自己也是用Javaagent方案

    2018-07-03
    4
    57
  • ZoQ-tans
    老师,您这个专栏完结了还会不会出其他专栏,你的每一篇我起码要听三四遍,我都是咬文嚼字的听,非常有用,非常好的内功心法

    作者回复: 非常感谢,老学究感到很欣慰,希望能对未来实践有帮助,专栏形式更多的是解决知识点的问题,后续专栏还没开始思考

    2018-06-30
    2
    16
  • antipas
    无痕埋点原理就是这样。像注解类框架也用到了比如retrofit

    作者回复: 是的

    2018-06-30
    15
  • 冯宇
    还可以基于JVM实现各种动态语言。比如groovy就是使用java开发的动态脚本语言

    作者回复: 不错,各种jvm语言也是一大亮点

    2018-09-30
    12
  • 胡馥春
    所有用到java反射的地方,底层都是采用了字节码操纵技术,老师,这么理解对吗?

    作者回复: 不是,Proxy这里是个特例,因为需要生成新的class

    2018-07-05
    3
  • mojo
    请问老师,使用classloader动态加载的外部jar包,应该如何正确的卸载?已经加载到systemclassloader……通过反射urlclassloader的addurl方法加进去的

    作者回复: 加载到system classloader...我理解卸载不了

    2018-07-17
    2
    2
  • rivers
    希望作者能详细的讲下,javaassist等其他代理模式的使用,砍掉了很多内容,尽量考虑下水平有限的读者
    2018-07-02
    6
  • 李飞
    越来越底层了,也越来越吃力,看来需要反复阅读才能吃透了
    2020-05-15
    2
  • 朱震震
    为什么需要动态加载,这个部分对系统有没有影响,会带来什么好处和坏处,痛点在哪,这些需要思考清楚。 好处解耦,实现动态的载入和卸载,监控等。缺点就是整体系统维护复杂度增高。这个技术通俗的理解就是使用了封装jvm识别的指令,然后生成字节码,然后使用加载类的方式加载,生成。具体细节还要详细研究
    2020-03-02
    2
收起评论
显示
设置
留言
15
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部