当前位置: 首页 > article >正文

JDK 24 Class File API 介绍

概述

JDK 24 引入的 Class File API 提供了一套类型安全的 API 用于操作 Java 类文件。这套 API 允许我们以编程方式读取、修改和创建 Java 类文件,而不需要直接处理底层的字节码。

注1:JDK 24 已于2025年3月18日正式发布,Release信息参见官方介绍。

注2:Class File API的前世今生,参见小子前作《JDK 24正式支持Class-File API》

三方库回顾

在 JDK 24 的 Class File API 之前,社区已经存在一些成熟且广泛使用的库来操作 Java 类文件。以下是一些流行的库列表:

  1. ASM: 一个非常流行且高性能的底层 Java 字节码操作和分析框架。它被许多其他库(如 cglib、Byte Buddy)和框架(如 Spring、Hibernate)广泛使用。
  2. Byte Buddy: 一个现代化的、类型安全的库,用于在运行时创建和修改 Java 类,无需了解字节码。它以其易于使用的流式 API 而闻名,并被 Mockito 等项目使用。
  3. Javassist (Java Programming Assistant): 提供两种级别的 API:源代码级别和字节码级别。源代码级别的 API 允许开发者像编辑 Java 源代码一样编辑类文件,而无需关心字节码细节。
  4. cglib (Code Generation Library): 主要用于通过生成字节码在运行时扩展 Java 类和实现接口。它是许多 AOP 和代理框架的基础,通常基于 ASM 构建。
  5. BCEL (Apache Commons Byte Code Engineering Library): Apache Commons 项目的一部分,旨在提供一种简单的方式来分析、创建和操作(二进制)Java 类文件。虽然相对较老,但在某些项目中仍有使用。

这些库各有优缺点,适用于不同的场景和复杂度需求。JDK 24 的 Class File API 提供了一个标准化的、内置于 JDK 的替代方案。下面介绍一下相关核心类及使用方法。

JDK API核心类关系图

先看一下API框架的核心类间的关系图。

creates
creates
uses
uses
contains
contains
contains
uses
uses
uses
uses
uses
uses
uses
«interface»
ClassFile
+parse(bytes: byte[]) : ClassModel
+build(thisClass: ClassDesc, handler: Consumer<ClassBuilder>) : byte[]
+buildTo(path: Path, thisClass: ClassDesc, handler: Consumer<ClassBuilder>) : void
«interface»
ClassModel
+thisClass() : ClassDesc
+superclass() : Optional<ClassDesc>
+interfaces() : List<ClassDesc>
+flags() : AccessFlags
+fields() : List<FieldModel>
+methods() : List<MethodModel>
+constantPool() : ConstantPool
«interface»
ClassBuilder
+withVersion(major: int, minor: int) : ClassBuilder
+withFlags(flags: AccessFlag...) : ClassBuilder
+withSuperclass(desc: ClassDesc) : ClassBuilder
+withInterfaces(interfaces: ClassDesc...) : ClassBuilder
+withField(name: String, descriptor: ClassDesc, handler: Consumer<FieldBuilder>) : ClassBuilder
+withMethod(name: String, descriptor: MethodTypeDesc, methodFlags: int, handler: Consumer<MethodBuilder>) : ClassBuilder
«interface»
FieldModel
+fieldName() : Utf8Entry
+fieldType() : Utf8Entry
+flags() : AccessFlags
«interface»
MethodModel
+methodName() : Utf8Entry
+methodType() : Utf8Entry
+flags() : AccessFlags
«interface»
MethodBuilder
+withFlags(flags: AccessFlag...) : MethodBuilder
+withCode(code: Consumer<CodeBuilder>) : MethodBuilder
«interface»
CodeBuilder
+getstatic(owner: ClassDesc, name: String, type: ClassDesc) : CodeBuilder
+ldc(value: String) : CodeBuilder
+invokevirtual(owner: ClassDesc, name: String, descriptor: MethodTypeDesc) : CodeBuilder
+return_() : CodeBuilder
«interface»
ConstantPool
+size() : int
+entryByIndex(index: int) : ConstantPoolEntry
«interface»
FieldBuilder
+withFlags(flags: int) : FieldBuilder
+withFlags(flags: AccessFlag...) : FieldBuilder
AccessFlags
ClassDesc
Utf8Entry

核心类介绍

1. ClassModel

ClassModel 是类文件的主要模型,代表一个完整的类文件结构。它是一个不可变的类文件描述,提供了访问类元数据(如类名、访问标志等)和子结构(如字段、方法、属性等)的方法。ClassModel 是延迟加载的,大多数类文件部分在实际需要之前不会被解析。由于延迟加载的特性,这些模型可能不是线程安全的。此外,由于解析是延迟进行的,访问器方法的调用可能会因为类文件格式错误而抛出 IllegalArgumentException

ClassModel 可以被视为一个树形结构,其中包含字段、方法和属性等子结构。每个子结构(如 MethodModel)又可以有它自己的子结构(如属性、CodeModel 等)。除了通过显式导航方法(如 ClassModel.methods())访问特定部分外,ClassModel 还提供了一个类元素流视图,允许我们以线性方式遍历所有类元素。

public interface ClassModel {// 获取类名ClassDesc thisClass();// 获取父类Optional<ClassDesc> superclass();// 获取实现的接口列表List<ClassDesc> interfaces();// 获取类的访问标志AccessFlags flags();// 获取类的字段列表List<FieldModel> fields();// 获取类的方法列表List<MethodModel> methods();// 获取类的属性列表List<Attribute<?>> attributes();// 获取常量池ConstantPool constantPool();// 获取类元素流Stream<ClassElement> elementStream();
}

2. FieldModel

FieldModel 代表类中的一个字段。它是一个不可变的字段描述,提供了访问字段元数据(如字段名、类型、访问标志等)和属性列表的方法。FieldModel 是延迟加载的,字段的详细信息在实际需要之前不会被解析。

public interface FieldModel {// 获取字段名Utf8Entry fieldName();// 获取字段类型Utf8Entry fieldType();// 获取字段的访问标志AccessFlags flags();// 获取字段的属性列表List<Attribute<?>> attributes();// 获取字段元素流Stream<FieldElement> elementStream();
}

3. MethodModel

MethodModel 代表类中的一个方法。它是一个不可变的方法描述,提供了访问方法元数据(如方法名、描述符、访问标志等)和属性列表的方法。MethodModel 是延迟加载的,方法的详细信息(包括方法体)在实际需要之前不会被解析。

public interface MethodModel {// 获取方法名Utf8Entry methodName();// 获取方法描述符Utf8Entry methodType();// 获取方法的访问标志AccessFlags flags();// 获取方法的属性列表List<Attribute<?>> attributes();// 获取方法元素流Stream<MethodElement> elementStream();
}

4. ClassFile

ClassFile 是一个提供解析、转换和生成类文件能力的接口。它作为一个上下文,包含一组选项,这些选项会影响解析和生成的方式。主要通过 ClassFile.of() 静态方法获取实例。

public interface ClassFile {// 解析类文件字节数组ClassModel parse(byte[] bytes);// 创建新的类文件byte[] build(ClassDesc thisClass, Consumer<? super ClassBuilder> handler);// 创建新的类文件并写入到文件系统void buildTo(Path path, ClassDesc thisClass, Consumer<? super ClassBuilder> handler) throws IOException;// 获取 ClassFile 实例static ClassFile of(Option... options) {// ...}
}

5. ClassBuilder

ClassBuilder 是一个用于构建类文件的接口。它提供了设置类版本、访问标志、父类、接口、字段和方法的能力。主要通过 ClassFile.build() 方法获取实例。

public interface ClassBuilder {// 设置类版本ClassBuilder withVersion(int major, int minor);// 设置类访问标志ClassBuilder withFlags(AccessFlag... flags);// 设置父类ClassBuilder withSuperclass(ClassDesc desc);// 设置接口列表ClassBuilder withInterfaces(ClassDesc... interfaces);// 添加字段ClassBuilder withField(String name, ClassDesc descriptor,Consumer<? super FieldBuilder> handler);// 添加方法ClassBuilder withMethod(String name, MethodTypeDesc descriptor, int methodFlags,Consumer<? super MethodBuilder> handler);
}

6. FieldBuilder

FieldBuilder 是一个用于构建字段的接口。主要通过 ClassBuilder.withField() 方法获取实例。如果不需要配置属性,可以使用 withFlags 重载方法来跳过处理器。

public interface FieldBuilder {// 设置字段访问标志(通过位掩码)FieldBuilder withFlags(int flags);// 设置字段访问标志(通过AccessFlag枚举)FieldBuilder withFlags(AccessFlag... flags);
}

7. MethodBuilder

MethodBuilder 是一个用于构建或修改方法的接口。它允许开发者设置方法的访问标志和添加字节码指令。主要通过 ClassBuilder.withMethod() 获取实例。

public interface MethodBuilder {// 设置方法访问标志MethodBuilder withFlags(AccessFlag... flags);// 添加方法体的字节码指令MethodBuilder withCode(Consumer<CodeBuilder> code);
}

8. CodeBuilder

CodeBuilder 是一个用于构建方法体的接口。它提供了大量的工厂方法来生成字节码指令。主要通过 MethodBuilder.withCode() 获取实例。

CodeBuilder 提供了丰富的字节码指令生成方法,包括:

  1. 标签和局部变量管理:创建标签、管理局部变量槽位等
  2. 控制流指令:如分支、条件判断、循环等
  3. 局部变量操作:如加载和存储局部变量
  4. 字段访问:如获取和设置字段值
  5. 方法调用:如调用各种类型的方法
  6. 数组操作:如数组元素的加载和存储
  7. 类型转换:如基本类型之间的转换
  8. 常量加载:如加载各种类型的常量
  9. 异常处理:如 try-catch 结构
  10. 调试信息:如行号和局部变量表

这些方法使得生成字节码变得更加简单和直观,不需要直接处理底层的字节码指令。每个方法都返回 CodeBuilder 实例,支持链式调用,使得代码更加简洁易读。

public interface CodeBuilder {// 标签和局部变量相关Label newLabel();                    // 创建新标签int allocateLocal(TypeKind type);    // 分配局部变量槽位// 控制流相关CodeBuilder branch(Opcode opcode, Label target);  // 分支指令CodeBuilder ifThen(Consumer<CodeBuilder> then);   // if-then 结构// 局部变量操作CodeBuilder loadLocal(TypeKind type, int slot);   // 加载局部变量CodeBuilder storeLocal(TypeKind type, int slot);  // 存储局部变量// 字段访问CodeBuilder fieldAccess(Opcode opcode, ClassDesc owner, String name, ClassDesc type);// 方法调用CodeBuilder invoke(Opcode opcode, ClassDesc owner, String name, MethodTypeDesc type, boolean isInterface);// 常量加载CodeBuilder loadConstant(ConstantDesc value);  // 加载常量// 异常处理CodeBuilder exceptionCatch(Label start, Label end, Label handler, ClassEntry catchType);  // 异常捕获// 调试信息CodeBuilder lineNumber(int line);  // 行号// 常用指令的便捷方法CodeBuilder getstatic(ClassDesc owner, String name, ClassDesc type);  // 获取静态字段CodeBuilder ldc(String value);  // 加载字符串常量CodeBuilder invokevirtual(ClassDesc owner, String name, MethodTypeDesc descriptor);  // 调用虚拟方法CodeBuilder return_();  // 返回
}

9. ConstantPool

ConstantPool 代表类文件的常量池。它提供了一个延迟加载的、只读的常量池视图。类文件中的许多重要内容都存储在常量池中,如类名、方法名、字段名、字符串字面量等。常量池项通常以各种 PoolEntry 子类型的形式暴露,如 ClassEntryUtf8Entry

常量池项也可以通过模型和元素暴露。例如,在遍历类文件时,InvokeInstruction 元素暴露的 owner() 方法对应常量池中的 Constant_Class_info 条目。

public interface ConstantPool {// 获取常量池大小int size();// 通过索引获取常量池项ConstantPoolEntry entryByIndex(int index);
}

使用示例

1. 类文件分析

// 读取并分析类文件
byte[] classBytes = Files.readAllBytes(classFilePath);
ClassModel classModel = ClassFile.of().parse(classBytes);// 遍历字段和方法
for (FieldModel fm : classModel.fields()) {System.out.printf("Field %s%n", fm.fieldName().stringValue());
}
for (MethodModel mm : classModel.methods()) {System.out.printf("Method %s%n", mm.methodName().stringValue());
}// 使用类元素流遍历
for (ClassElement ce : classModel) {switch (ce) {case MethodModel mm -> System.out.printf("Method %s%n", mm.methodName().stringValue());case FieldModel fm -> System.out.printf("Field %s%n", fm.fieldName().stringValue());default -> { }}
}

2. 分析类依赖

// 分析类文件中的依赖关系
ClassModel classModel = ClassFile.of().parse(classBytes);
Set<ClassDesc> dependencies = new HashSet<>();// 使用显式遍历
for (ClassElement ce : classModel) {if (ce instanceof MethodModel mm) {for (MethodElement me : mm) {if (me instanceof CodeModel xm) {for (CodeElement e : xm) {switch (e) {case InvokeInstruction i -> dependencies.add(i.owner().asSymbol());case FieldInstruction i -> dependencies.add(i.owner().asSymbol());default -> { }}}}}}
}// 使用流式处理
Set<ClassDesc> dependencies2 = classModel.elementStream().flatMap(ce -> ce instanceof MethodModel mm ? mm.elementStream() : Stream.empty()).flatMap(me -> me instanceof CodeModel com ? com.elementStream() : Stream.empty()).<ClassDesc>mapMulti((xe, c) -> {switch (xe) {case InvokeInstruction i -> c.accept(i.owner().asSymbol());case FieldInstruction i -> c.accept(i.owner().asSymbol());default -> { }}}).collect(toSet());

3. 类文件修改

// 修改现有类文件
ClassBuilder builder = ClassFile.of().transform(classModel);
builder.withField(...).withMethod(...).build();

4. 创建新类

// 创建新的类文件
ClassBuilder builder = ClassFile.of().build(ClassDesc.of("com/example/NewClass"));
builder.withSuperclass(ClassDesc.of("java/lang/Object")).withMethod(...).build();

5. 修改方法字节码

// 修改方法的字节码
builder.withMethod("methodName", "()V", methodBuilder -> {methodBuilder.withCode(codeBuilder -> {codeBuilder.getstatic(...).ldc(...).invokevirtual(...).return_();});
});

API 优点

  1. 类型安全:提供了类型安全的类文件操作,减少了运行时错误
  2. 功能完整:支持类文件的读取、修改和创建
  3. 字节码操作:可以方便地操作字节码
  4. 结构完整:提供了完整的类文件结构模型
  5. 注解支持:支持注解和属性的处理

应用场景

  1. 类文件分析工具:用于分析类文件的结构和内容
  2. 字节码增强:在运行时修改类的行为
  3. 动态类生成:在运行时创建新的类
  4. 类文件转换:将类文件转换为其他格式
  5. 代码注入:向现有类中注入新的代码

注意事项

  1. 使用 Class File API 时需要确保对类文件的操作符合 Java 虚拟机规范
  2. 修改类文件时要注意保持类文件结构的完整性
  3. 在处理字节码时要确保生成的字节码是有效的
  4. 注意处理类文件版本兼容性问题

预告

下一期小子给各位看官详细介绍API的使用…

相关文章:

JDK 24 Class File API 介绍

概述 JDK 24 引入的 Class File API 提供了一套类型安全的 API 用于操作 Java 类文件。这套 API 允许我们以编程方式读取、修改和创建 Java 类文件&#xff0c;而不需要直接处理底层的字节码。 注1&#xff1a;JDK 24 已于2025年3月18日正式发布&#xff0c;Release信息参见官…...

C++23:现代C++的模块化革命与零成本抽象新高度

以下代码为伪代码&#xff0c;仅供参考 一、标准库的范式突破 1. std::expected&#xff1a;类型安全的错误处理 std::expected<DataPacket, ErrorCode> parsePacket(ByteStream& stream) {if (stream.header_valid()) return decode_packet(stream);elsereturn s…...

《K230 从熟悉到...》矩形检测

《K230 从熟悉到...》矩形检测 《庐山派 K230 从熟悉到...》矩形检测 矩形检测技术是一种广泛应用于电子图像处理的核心技术。它通过识别和分析图像中的矩形结构&#xff0c;为各种应用提供基础支持。从传统图像处理算法到现代深度学习技术&#xff0c;矩形检测的实现途径多种多…...

Unity 面向对象实战:掌握组件化设计与脚本通信,构建玩家敌人交互

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

3. 第三放平台部署deepseek

有时候我们会发现使用deepseek服务器&#xff0c;异常卡顿&#xff0c;这是由于多方面原因造成的&#xff0c;比如说访问人数过多等。想要解决这个问题&#xff0c;我们可以选择第三方平台进行部署 第三方平台 我们可以选择的第三方平台很多&#xff0c;比如硅基流动、秘塔搜索…...

【C++指针】搭建起程序与内存深度交互的桥梁(下)

&#x1f525;&#x1f525; 个人主页 点击&#x1f525;&#x1f525; 每文一诗 &#x1f4aa;&#x1f3fc; 往者不可谏&#xff0c;来者犹可追——《论语微子篇》 译文&#xff1a;过去的事情已经无法挽回&#xff0c;未来的岁月还可以迎头赶上。 目录 C内存模型 new与…...

.NET开发基础知识1-10

1. 依赖注入&#xff08;Dependency Injection&#xff09; 技术知识&#xff1a;依赖注入是一种设计模式&#xff0c;它允许将对象的依赖关系从对象本身中分离出来&#xff0c;通过构造函数、属性或方法参数等方式注入到对象中。这样可以提高代码的可测试性、可维护性和可扩展…...

IEEE PDF Xpress校验出现 :字体无法嵌入问题以及pdf版本问题

文章目录 问题描述一、字体嵌入问题首先查看一下&#xff0c;哪些字体没有被嵌入查看window的font文件夹里的字体下载字体的网站修复字体嵌入问题 二、pdf版本不对 问题描述 在处理IEEE的camera ready的时候&#xff0c;提交到IEEE express的文件没有办法通过validate&#xf…...

cookie详解

一、cookie出现原因 http是无状态的&#xff0c;浏览器无法记录当前是哪个人浏览的&#xff0c;所以出现了cookie 作用&#xff1a;会话状态管理&#xff08;用户登录状态、购物车、游戏分数&#xff09;、个性化设置&#xff08;主题、自定义设置&#xff09;、浏览器行为跟…...

Mayo Clinic Platform在人工智能医疗领域的现状及启示意义研究

一、引言 1.1 研究背景与意义 在科技飞速发展的当下,人工智能(AI)已逐渐渗透至各个行业,医疗领域作为关乎人类生命健康的重要领域,也迎来了人工智能技术带来的深刻变革。人工智能医疗,作为人工智能与医疗行业深度融合的产物,正重塑着全球医疗的格局。 从全球范围来看,…...

Rust基础语法

以下是 Rust 语言基础语法的核心要点&#xff0c;结合与 JavaScript 的对比&#xff0c;帮助前端开发者快速掌握核心概念&#xff1a; 一、变量与常量 1. 变量声明 Rust&#xff1a;变量默认不可变&#xff0c;需用 mut 显式声明可变性。let x 5; // 不可变变量 le…...

如何将 Java 应用做成 EXE 的可执行软件

目录 前言一、情景介绍二、实现步骤1. 打 Jar 包2. 编写 bat 批处理文件3. bat 转 exe 前言 最近使用 GUI 帮朋友写了一个软件&#xff0c;为了方便他处理工作上的重复性且很麻烦的事情&#xff0c;程序是使用 Java 写的&#xff0c;就不得不面对一个问题&#xff1a;我必须将…...

第一篇:系统分析师首篇

目录 一、目标二、计划三、完成情况1.宏观思维导图2.过程中的团队管理和其它方面的思考 四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 一、目标 通过参加考试&#xff0c;训练学习能力&#xff0c;而非单纯以拿证为目的。 1.在复…...

自动关机监控器软件 - 您的电脑节能助手

## 自动关机监控器 - 您的电脑节能助手 自动关机监控器是一款基于Python开发的实用工具&#xff0c;旨在帮助用户节省电力资源并延长电脑使用寿命。该程序通过监控用户的鼠标和键盘活动&#xff0c;在设定的无活动时间后自动关闭计算机&#xff0c;特别适合需要长时间离开电脑但…...

线程概念与控制(中)

线程概念与控制&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/146464905?sharetypeblogdetail&sharerId146464905&sharereferPC&sharesourceSmall_entreprene&sharefrommp_from_link我们经过上一篇的学习&#xff0c;接…...

K8S学习之基础六十二:helm部署memcached服务

helm部署memcached服务 #安装memcached的Chart docker load -i memcache_1_4_36.tar.gz #如果k8s用的是docker做容器运行时&#xff0c;用docker load -i导出镜像 ctr -nk8s.io images import memcache_1_4_36.tar.gz #如果k8s用的是containerd做容器运行时&#xff0c;用ctr…...

CPU 超线程技术以及如何关闭CPU超线程功能

CPU超线程技术介绍 CPU 超线程技术&#xff08;Hyper-Threading Technology&#xff0c;HT&#xff09;是英特尔提出的一种同时多线程&#xff08;Simultaneous Multi-Threading, SMT&#xff09;​实现方式&#xff0c;其核心思想是通过逻辑层面的优化&#xff0c;让单个物理…...

Redis 源码硬核解析系列专题 - 第二篇:核心数据结构之SDS(Simple Dynamic String)

1. 引言 Redis没有直接使用C语言的标准字符串(以\0结尾的字符数组),而是自定义了SDS(Simple Dynamic String)。SDS是Redis的基础数据结构之一,广泛用于键值存储、命令参数等场景。本篇将深入剖析SDS的实现原理、优势以及源码细节。 2. 为什么不用C标准字符串? C字符串…...

1--当「穷举」成为艺术:CTF暴力破解漏洞技术从入门到入刑指南(知识点讲解版)

当「穷举」成为艺术&#xff1a;CTF暴力破解漏洞技术从入门到入刑指南 引言&#xff1a;论暴力破解的哲学意义 “世界上本没有漏洞&#xff0c;密码设得简单了&#xff0c;便成了漏洞。” —— 鲁迅&#xff08;并没有说过&#xff09; 想象你是个不会撬锁的小偷&#xff0c;面…...

DHCP报文的详细流程

在DHCP协议的工作流程中&#xff0c;​Discover和Request报文使用广播MAC地址&#xff0c;而Offer和ACK报文通常使用单播MAC地址。这种差异源于DHCP协议的设计逻辑和网络通信的实际需求&#xff0c;具体原因如下&#xff1a; ​1. DHCP报文交互流程 DHCP的完整流程分为四个阶段…...

通信协议和特征

文章目录 双工时钟电平串并行 双工 全双工&#xff1a;全双工通信允许同一时刻数据在两个方向上同时进行传输。一般来说&#xff0c;全双工的通信都有两根数据线&#xff0c;一根发送&#xff0c;一根接收&#xff0c;二者互不影响。半双工&#xff1a;允许数据在两个方向上传…...

Python 循环全解析:从语法到实战的进阶之路

一、问答题 &#xff08;1&#xff09;下面的循环体被重复了多少次?每次循环的输出结果是什么? i1 while i < 10:if i % 2 0:print(i)死循环&#xff0c;没有输出结果 i1 while i < 10:if i % 2 0:print(i)i l死循环&#xff0c;没有输出结果 i 1 while i< 10…...

The Rust Programming Language 学习 (七)

常见集合 使用 Vector 存储表 Vec<T>&#xff0c;也被称为 vector。vector 允许我们在一个单独的数据结构中储存多于一个的值&#xff0c;它在内存中彼此相邻地排列所有的值。vector 只能储存相同类型的值。它们在拥有一系列项的场景下非常实用 新建Vector 为了创建一…...

[GXYCTF2019]禁止套娃1 [GitHack] [无参数RCE]

Git基础 Git信息泄露原理解析及利用总结 - FreeBuf网络安全行业门户 CTF中的GIT泄露_ctf git泄露-CSDN博客 Git结构 dirsearch扫出来一大堆东西&#xff08;然而这些并没有什么屁用&#xff09; 但也算起码了解了git结构了吧 /.git/HEAD&#xff1a;表示当前HEAD指针的指…...

从ChatGPT到AutoGPT——AI Agent的范式迁移

一、AI Agent的范式迁移 1. ChatGPT的局限性与Agent化需求 单轮对话的“工具属性” vs. 多轮复杂任务的“自主性” ChatGPT 作为强大的生成式AI,虽然能够进行连贯对话,但本质上仍然是“工具型”AI,依赖用户提供明确的指令,而无法自主规划和执行任务。 人类介入成本过高:提…...

stock-pandas,一个易用的talib的替代开源库。

原创内容第841篇&#xff0c;专注智能量化投资、个人成长与财富自由。 介绍一个ta-lib的平替——我们来实现一下&#xff0c;最高价突破布林带上轨&#xff0c;和最低价突破布林带下轨的可视化效果&#xff1a; cross_up_upper stock[high].copy()# cross_up_upper 最高价突破…...

Spring Cloud Gateway详细介绍简单案例

文章目录 1、Spring Cloud Gateway 详细介绍1.1. 统一入口&#xff08;Single Entry Point&#xff09;1.2. 请求路由&#xff08;Request Routing&#xff09;1.3. 负载均衡&#xff08;Load Balancing&#xff09;1.4. 流量控制&#xff08;Rate Limiting&#xff09;1.5. 身…...

鸿蒙原生开发之状态管理V2

一、ArkTS状态变量的定义&#xff1a; State&#xff1a;状态&#xff0c;指驱动UI更新的数据。用户通过触发组件的事件方法&#xff0c;改变状态数据。状态数据的改变&#xff0c;引起UI的重新渲染。 在鸿蒙原生开发中&#xff0c;使用ArkTS开发UI的时候&#xff0c;我们可以…...

矩阵中对角线的遍历问题【C++】

1&#xff0c;按对角线进行矩阵排序 题目链接&#xff1a;3446. 按对角线进行矩阵排序 - 力扣&#xff08;LeetCode&#xff09; 【题目描述】 对于一个m*n的矩阵grid&#xff0c;要求对该矩阵进行 变换&#xff0c;使得变换后的矩阵满足&#xff1a; 主对角线右上的所有对角…...

Python小练习系列 Vol.4:迷宫寻路(回溯 + DFS)

&#x1f9e0; Python小练习系列 Vol.4&#xff1a;迷宫寻路&#xff08;回溯 DFS&#xff09; &#x1f6aa; 本期我们将探索一个二维世界&#xff0c;借助回溯算法帮助角色走出迷宫&#xff01;这是学习路径搜索类题目的经典案例。 &#x1f9e9; 一、题目描述 给定一个二维…...