AICon 深圳站 Keynote 嘉宾官宣!共探AI价值转化的实践路径 了解详情
写点什么

Java 架构师:ASM 已经过时,建议使用类文件 API 简化开发

  • 2024-01-07
    北京
  • 本文字数:2170 字

    阅读完需:约 7 分钟

大小:605.33K时长:03:26
Java架构师:ASM已经过时,建议使用类文件API简化开发

JEP 457,类文件API(Class-File API,预览),最近已经集成到了 JDK 22 中。该 JEP 建议提供一个 API 来解析、生成和转换 Java 类文件。它最初将作为 JDK 中 Java 字节码操作和分析框架ASM的内部替代品,并计划将其作为公共 API 开放。甲骨文的 Java 语言架构师Brian Goetz将 ASM 描述为“带有大量遗留包袱的旧代码库”,并提供了关于该草案将如何发展并最终取代 ASM 的背景信息

 

类文件 API 的核心是几项关键原则。首先,它将类文件实体(比如字段、方法、属性和字节码指令)均视为不可变对象。这种不可变的表述确保在类文件转换时可以可靠地进行共享。该 API 采用树形结构来反映类文件的层次结构,从而支持用户驱动的导航以进行高效地解析。它还强调了解析过程的延迟性,即只会处理满足用户需求所需的类文件。

 

类文件 API 位于java.lang.classfile包及其子包中,包含三个主要的抽象,即元素、构建器和转换。元素是类文件组件的不可变描述。构建器对应于每种复合元素,可以使用特定的构建方法来方便地构造类文件。转换表示在构建过程中修改元素的函数。

该 API 还引入了使用模式解析类文件的新方法,与 ASM 基于访问者(visitor)的方式有所不同。这支持更直接和更简洁的表达式,利用了 Java 的模式匹配功能。例如,开发人员可以遍历 CodeModel 中的指令,并匹配感兴趣的元素,以完成像依赖图构造这样的任务。

 

考虑如下的样例:

CodeModel code = ...;Set<ClassDesc> deps = new HashSet<>();for (CodeElement e : code) {    switch (e) {        case FieldInstruction f  -> deps.add(f.owner());        case InvokeInstruction i -> deps.add(i.owner());        // ... and so on for instanceof, cast, etc ...    }}
复制代码

这个代码片段展示了使用模式匹配来解析 Code 属性以收集类依赖关系图的依赖,迭代指令并匹配特定的类型。

 

使用构建器生成类文件是另一项关键特性。该 API 颠覆了使用构造函数或工厂创建构建器的传统习惯,相反,客户端提供一个接受构建器的 lambda。这种方法提供了更具体和透明的代码生成,并且可以重放操作序列。它还为管理块范围、局部变量索引计算和标签管理提供了更高级的便利性。

 

下面的代码展示了如何使用构建器生成方法,演示了该 API 具体且透明的代码生成方式。

ClassBuilder classBuilder = ...;classBuilder.withMethod("fooBar", MethodTypeDesc.of(CD_void, CD_boolean, CD_int), flags,    methodBuilder -> methodBuilder.withCode(codeBuilder -> {        Label label1 = codeBuilder.newLabel();        Label label2 = codeBuilder.newLabel();        codeBuilder.iload(1)            .ifeq(label1)            .aload(0)            .iload(2)            .invokevirtual(ClassDesc.of("Foo"), "foo", MethodTypeDesc.of(CD_void, CD_int))            .goto_(label2)            .labelBinding(label1)            .aload(0)            .iload(2)            .invokevirtual(ClassDesc.of("Foo"), "bar", MethodTypeDesc.of(CD_void, CD_int))            .labelBinding(label2)            .return_();    });
复制代码

类文件的转换功能同样值得注意。解析和生成方法保持了一致,这样转换可以无缝进行。例如,开发人员可以处理一个类,以便于删除特定的方法,或者通过应用各种转换来改变方法体。

 

下面的代码片段展示了 API 的转换类文件的功能,演示了在转换过程中如何有选择地修改或替换类元素。

ClassFile cf = ClassFile.of();ClassModel classModel = cf.parse(bytes);byte[] newBytes = cf.transform(classModel, (classBuilder, ce) -> {    if (ce instanceof MethodModel mm) {        classBuilder.transformMethod(mm, (methodBuilder, me)-> {            if (me instanceof CodeModel cm) {                methodBuilder.transformCode(cm, (codeBuilder, e) -> {                    switch (e) {                        case InvokeInstruction i                                when i.owner().asInternalName().equals("Foo") ->                            codeBuilder.invokeInstruction(i.opcode(), ClassDesc.of("Bar"),                                                           i.name().stringValue(),                                                          i.typeSymbol(), i.isInterface());                        default -> codeBuilder.with(e);                    }                });            }            else                methodBuilder.with(me);        });    }    else        classBuilder.with(ce);});
复制代码

JEP 457 具有变革性的一个方面是如何解决 Java 生态系统中类文件格式的快速发展所带来的挑战。通过提供与 JDK 一起演进的标准 API,它能够确保使用该 API 的框架和工具会自动支持来自最新 JDK 的类文件。这种能力对于新语言和 VM 特性非常重要,它们在类文件中可能会有相应地表述。

 

总之,JEP 457 的类文件 API 是一种具有前瞻性的解决方案,符合 Java 开发的现代化需求。它的设计原则、抽象和转换功能使其成为 Java 开发人员的强大工具,增强了 Java 生态系统中类文件管理的效率和可靠性。

 

原文链接:

 JEP 457: Streamlining Java Development with the Class-File API

2024-01-07 08:0010127

评论

发布
暂无评论
发现更多内容

【云服务器】云计算平台的架构是什么样的?

Finovy Cloud

云服务器 GPU服务器

直播回顾 | 7000字干货,深析区块链+汽车供应链金融的应用价值

旺链科技

区块链 产业区块链 供应链金融

【LeetCode】 删除二叉搜索树中的节点Java题解

Albert

LeetCode 6月月更

5G+实时云渲染:交互实时云看车革新购车体验

3DCAT实时渲染

5G 汽车之家 汽车 元宇宙 实时云渲染

Flutter 图片库重磅开源!

阿里巴巴终端技术

flutter 开源 native 客户端

龙蜥开发者说:不忘初心,方得始终 | 第 7 期

OpenAnolis小助手

开源 cpu 龙蜥开发者说 飞腾 不忘初心

【高并发】在高并发环境下该如何构建应用级缓存?

冰河

并发编程 多线程 高并发 异步编程 6月月更

移动平台打造新生态 | 助力企业跨业务、一站式、全场景的系统建设

BeeWorks

选择天翼云混合云管理平台的五大理由

天翼云开发者社区

玩转云端|一文读懂天翼云CDN升级重点

天翼云开发者社区

数字先锋| 天翼云牵手中能融合

天翼云开发者社区

使用 LakeSoul 构建实时机器学习样本库

Geek_a02d1e

机器学习 大数据 开源 新基建 湖仓一体

博云容器云产品族:如何实现让“Any APP on Any Kubernetes”?

BoCloud博云

云原生 容器云

多模态语义检索 | 基于 MetaSpore 快速部署 HuggingFace 预训练模型

Geek_a02d1e

机器学习 深度学习 开源 AI 多模态

天猫精灵语音技能单轮对话表达式的参数定义

汪子熙

人工智能 机器学习 聊天机器人 机器人 6月月更

【Spring 学习笔记(一)】第一个Spring程序与IoC思想

倔强的牛角

6月月更

哈希游戏开发竞猜系统哈希值hash算法

薇電13242772558

哈希算法

科创人·神州数码集团CIO沈旸:最佳实践模式正在失灵,开源加速分布式创新

科创人

样品管理系统解决方案

低代码小观

Lims LIMS实验室信息管理系统 LIMS系统

当AI抄起了水表

华为云开发者联盟

人工智能 modelarts workflow 智能水务

leetcode 417. Pacific Atlantic Water Flow 太平洋大西洋水流问题

okokabcd

LeetCode 搜索 数据结构与算法

一篇文章带你彻底了解哈希表

武师叔

算法 哈希表 6月月更

AI“爷青回”:一键找回童年记忆

最新动态

Java 中三大类数据类型

迷篱

InfoQ 极客传媒 15 周年庆征文|一文读懂分布式系统本质:高吞吐、高可用、可扩展

No Silver Bullet

架构 分布式系统 可扩展 6月月更 InfoQ极客传媒15周年庆

函数节流和函数防抖和他们的区别

工边页字

JavaScript 性能优化 前端 6月月更

2022年中国新能源汽车换电市场发展洞察

易观分析

新能源汽车

华为云GaussDB首席架构师冯柯:摘取皇冠上的明珠,华为云数据库的创新与探索

华为云开发者联盟

数据库 华为云 GaussDB 国产数据库

应用流程挖掘,发现潜在RPA可实施的场景,助力银行优化业务流程

易观分析

RPA

撑算力之帆,天翼云助力数字时代逐潮者远航

天翼云开发者社区

这个API文档,太拽了吧!

Liam

前端 Postman API API文档 开放api

Java架构师:ASM已经过时,建议使用类文件API简化开发_编程语言_A N M Bazlur Rahman_InfoQ精选文章