Java模块化强封装与反射访问:--add-opens参数原理、应用与迁移实践
1. 项目概述为什么我们需要关注--add-opens这个参数如果你最近在升级到 Java 9 或更高版本比如现在主流的 Java 11, 17, 21后运行一些老项目或者使用某些第三方库时在控制台看到了类似java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String java.lang.String.value accessible: module java.base does not “opens” java.lang to unnamed module的错误那么恭喜你你遇到了 Java 模块化系统带来的一个经典“拦路虎”。这个错误信息的核心直指 Java 平台模块系统JPMS引入的强封装性。而--add-opens这个 JVM 启动参数就是官方留给我们的“后门钥匙”之一。简单来说在 Java 9 之前我们可以通过反射Reflection几乎“为所欲为”地访问任何类、任何字段和方法包括 JDK 内部的私有 API比如sun.misc.Unsafe。这带来了灵活性但也导致了严重的安全性和可维护性问题——你的代码可能深度依赖于某个未公开的内部实现一旦 JDK 升级你的程序就崩溃了。为了根治这个问题Java 9 引入了模块化将 JDK 自身也拆分为模块如java.base并且默认情况下一个模块的私有 API非exports的包对其他模块包括我们写的“未命名模块”是封闭的反射也无法穿透这层壁垒。--add-opens参数的作用就是在运行时临时、定向地打开一个模块的某个包允许其他模块特别是我们那些尚未模块化的、处于“未命名模块”中的老代码通过反射来访问它。这相当于对模块系统的强封装规则做了一个特例豁免。理解并正确使用这个参数是让遗留代码平滑迁移到新版本 Java或是与某些尚未适配模块化的第三方库协同工作的关键技能。接下来我会拆解这个参数的具体语法、应用场景并给出从诊断到解决的一整套实操步骤。2. 核心原理与语法拆解--add-opens到底在做什么要解决问题必须先理解问题的根源和工具的原理。我们不能只会“抄命令”更要明白命令背后的逻辑。2.1 模块化与强封装错误的根源在 Java 9 中每个模块都有一个module-info.java描述符其中声明了该模块对外导出的包exports以及它依赖哪些模块requires。例如java.base模块是 JDK 最核心的模块它包含了java.lang,java.util等基础包。它只显式导出了部分包供其他模块使用。当我们使用反射去访问一个模块中未导出的包下的类成员时JPMS 就会抛出InaccessibleObjectException。这就是强封装在起作用它阻止了外部代码包括通过反射访问模块的内部实现细节。2.2--add-opens参数语法详解--add-opens的完整语法格式是--add-opens 源模块/包名目标模块让我们以标题中的--add-opens java.base/java.langALL-UNNAMED为例分解每个部分源模块:java.base。这是我们要“打开”的模块即包含我们想通过反射访问的类的那个模块。包名:java.lang。这是源模块中具体的包路径。注意这里打开的是整个java.lang包意味着该包下所有类型类、接口的非公开成员都允许被反射访问。目标模块:ALL-UNNAMED。这是被允许访问源模块指定包的目标模块。ALL-UNNAMED是一个特殊的关键字代表所有未命名模块。什么是未命名模块绝大多数传统的、没有module-info.java文件的 JAR 包和应用在 Java 9 上运行时都会被自动归入“未命名模块”。所以ALL-UNNAMED基本上涵盖了所有我们写的老代码和未模块化的第三方库。其他常见的目标模块写法com.yourcompany.yourmodule: 指定另一个具体的模块名。这在你自己的模块化项目中进行模块间深度集成时可能用到。ALL-MODULE-PATH: 允许模块路径上的所有模块访问。这比ALL-UNNAMED范围更广慎用。重要提示--add-opens与另一个常见参数--add-exports的区别在于--add-exports只允许在编译时和通过普通 API 调用访问而--add-opens特别允许通过反射进行访问。对于解决反射访问错误必须使用--add-opens。3. 诊断与定位如何确定你需要添加哪个--add-opens参数看到错误信息后不要盲目地添加一个宽泛的--add-opens java.base/java.langALL-UNNAMED。正确的做法是精准定位。以下是诊断流程3.1 解读错误堆栈信息错误信息是你的第一手资料。仔细阅读堆栈跟踪StackTrace。关键信息通常在第一行或抛异常的那一行附近。示例错误Exception in thread main java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not opens java.lang to unnamed module 4520ebad at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178) ...诊断步骤找到异常类型java.lang.reflect.InaccessibleObjectException。这明确是模块访问性问题。找到关键描述Unable to make field private final byte[] java.lang.String.value accessible。这告诉我们试图访问的成员是java.lang.String类的私有字段value。找到根本原因module java.base does not “opens” java.lang to unnamed module。这是核心它明确指出源模块java.base需要打开的包java.lang目标模块unnamed module即ALL-UNNAMED由此我们就能精准地构造出参数--add-opens java.base/java.langALL-UNNAMED。3.2 处理复杂或模糊的错误有时错误信息可能不那么直接或者来自一个深层嵌套的库调用。你可以向上追溯堆栈找到最早触发这个反射操作的、属于你自己代码或你直接依赖的库的那一行。这有助于理解是哪个组件触发了这个问题。使用-XX:ShowModuleResolution等调试参数高级用法在极少数情况下为了更深入了解模块加载情况可以在启动命令中添加-XX:ShowModuleResolution来查看模块解析日志。但这通常信息量巨大主要用于复杂模块化应用的调试。搜索引擎与库官方文档将错误信息的关键部分如库名和访问的类复制到搜索引擎中很可能该库的新版本已经解决了这个问题或者其官方文档/Issue列表中有明确的解决方案和所需的--add-opens参数。4. 具体操作步骤在不同场景中如何应用参数知道了参数怎么构造接下来就是在正确的地方使用它。根据你的应用启动方式添加参数的位置有所不同。4.1 场景一命令行直接运行java -jar或java -cp这是最直接的方式。将--add-opens参数添加到java命令之后主类名或-jar参数之前。语法模板java [其他VM参数] --add-opens 源模块/包目标模块 [可以添加多个--add-opens] -jar your-application.jar # 或 java [其他VM参数] --add-opens 源模块/包目标模块 -cp your-classpath com.yourcompany.MainClass实操示例假设我们有一个 Spring Boot 老应用需要访问java.lang和java.lang.reflect同时某个库还需要访问java.management。java --add-opens java.base/java.langALL-UNNAMED \ --add-opens java.base/java.lang.reflectALL-UNNAMED \ --add-opens java.management/javax.managementALL-UNNAMED \ -jar my-springboot-app.jar注意事项参数顺序JVM 参数以-、-X、-XX或--开头的必须放在-jar或主类名之前。放在之后会被视为传递给主类的参数JVM 不会识别。多个参数如果需要打开多个包就重复使用多个--add-opens参数。每个参数只针对一个“模块/包对”。Windows 系统在 Windows CMD 中移除行尾的反斜杠\将所有参数写在一行用空格分隔。4.2 场景二在 IDEIntelliJ IDEA, Eclipse中运行/调试在开发环境中配置同样重要。IntelliJ IDEA 配置步骤打开“运行/调试配置”Run/Debug Configurations。找到你的应用配置如 Spring Boot、Application。在“配置”选项卡中找到“修改选项”Modify options下拉菜单。勾选“添加 VM 选项”Add VM options。在下方新出现的“VM 选项”VM options输入框中添加你的--add-opens参数。--add-opens java.base/java.langALL-UNNAMED --add-opens java.base/java.lang.reflectALL-UNNAMED应用并保存。之后运行或调试都会生效。Eclipse 配置步骤右键点击你的项目或启动类选择“运行方式” - “运行配置...”Run As - Run Configurations...。在左侧找到你的 Java 应用配置或在右侧“主类”Main class选择你的启动类。切换到“参数”Arguments选项卡。在“虚拟机参数”VM arguments文本框中添加--add-opens参数。点击“应用”Apply然后“运行”Run。4.3 场景三构建工具Maven, Gradle配置为了确保从构建到测试再到打包的整个生命周期都使用相同的参数最好在构建脚本中配置。Maven 配置在pom.xml中对于maven-surefire-plugin运行单元测试和maven-failsafe-plugin运行集成测试build plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-surefire-plugin/artifactId configuration argLine --add-opens java.base/java.langALL-UNNAMED --add-opens java.base/java.lang.reflectALL-UNNAMED /argLine /configuration /plugin !-- 类似配置 maven-failsafe-plugin -- /plugins /build对于spring-boot-maven-plugin打包可执行Jarplugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration jvmArguments --add-opens java.base/java.langALL-UNNAMED --add-opens java.base/java.lang.reflectALL-UNNAMED /jvmArguments /configuration /pluginGradle 配置在build.gradle或build.gradle.kts中对于测试任务tasks.named(test) { jvmArgs [ --add-opens, java.base/java.langALL-UNNAMED, --add-opens, java.base/java.lang.reflectALL-UNNAMED ] }对于 Spring Boot 应用的bootRun任务tasks.named(bootRun) { jvmArgs [ --add-opens, java.base/java.langALL-UNNAMED, --add-opens, java.base/java.lang.reflectALL-UNNAMED ] }在application插件中配置主类启动参数application { applicationDefaultJvmArgs [ --add-opens, java.base/java.langALL-UNNAMED, --add-opens, java.base/java.lang.reflectALL-UNNAMED ] }4.4 场景四容器化环境Dockerfile在 Docker 镜像中运行 Java 应用时需要在ENTRYPOINT或CMD指令的java命令中添加参数。Dockerfile 示例FROM openjdk:17-jdk-slim COPY target/my-app.jar /app/my-app.jar WORKDIR /app # 在 ENTRYPOINT 的 java 命令中添加参数 ENTRYPOINT [java, \ --add-opens, java.base/java.langALL-UNNAMED, \ --add-opens, java.base/java.lang.reflectALL-UNNAMED, \ -jar, my-app.jar]注意使用 JSON 数组格式[java, --add-opens, ...]来避免 shell 解析带来的问题。5. 高级策略与最佳实践超越简单的参数添加仅仅添加--add-opens是治标不治本。作为资深开发者我们应该追求更优雅、可持续的解决方案。5.1 精准化而非泛化避免使用ALL-UNNAMED打开过多包--add-opens java.base/java.langALL-UNNAMED打开了整个java.lang包。如果问题只出在访问String.value字段这有点“杀鸡用牛刀”。虽然对于java.base核心模块影响相对可控但这是一个坏习惯。更好的做法如果可能尽量将目标模块从ALL-UNNAMED缩小到具体的模块。例如如果你正在开发一个模块化应用你的模块com.myapp.core需要反射访问java.lang那么应该使用--add-opens java.base/java.langcom.myapp.core。这遵循了最小权限原则提升了安全性。现实考量对于大量使用未模块化第三方库的传统应用精确指定目标模块非常困难。此时使用ALL-UNNAMED是务实的选择。但心里要明白这是对模块化封装的一种妥协。5.2 根本解决升级库版本与重构代码--add-opens是临时解决方案。长期来看应该升级第三方依赖访问库的官方网站或 Maven 仓库查看其最新版本是否已经适配了 Java 9 模块化。很多主流库如 Spring Framework, Hibernate, Jackson, Log4j2的新版本都已经通过自身模块化声明module-info.java或使用其他技术如MethodHandles.Lookup的私有 API解决了反射访问问题。升级依赖通常是最好、最彻底的办法。重构自己的代码检查自己的代码是否真的有必要使用反射去访问 JDK 内部 API是否存在更标准、更稳定的替代方案例如以前可能用sun.misc.BASE64Encoder现在应该用java.util.Base64。减少对内部 API 的依赖是代码健康度的体现。5.3 使用--illegal-access参数进行诊断与过渡Java 9 到 16 为了平滑迁移提供了一个警告模式参数--illegal-access。--illegal-accesspermitJava 9-15 默认允许通过反射访问但会打印警告。这是发现问题的好方法。--illegal-accesswarn仅打印警告不允许访问行为同deny但会警告。--illegal-accessdenyJava 16 默认禁止非法访问直接抛出InaccessibleObjectException。这也是为什么在 Java 16 上之前能跑的应用突然报错的原因。诊断用法在升级到 Java 16 前可以先用--illegal-accesspermit和--illegal-accesswarn运行应用控制台会打印出所有非法的反射访问操作这为你系统性地收集需要添加的--add-opens参数提供了完美清单。5.4 创建自定义的启动脚本或包装器对于需要固定添加大量--add-opens参数的企业级应用建议创建一个启动脚本如start.sh或start.bat将复杂的 JVM 参数封装在里面。这样运维人员和开发者只需要执行简单的脚本命令而无需记忆一长串参数。示例start.sh#!/bin/bash JAVA_OPTS\ --add-opens java.base/java.langALL-UNNAMED \ --add-opens java.base/java.lang.reflectALL-UNNAMED \ --add-opens java.base/java.ioALL-UNNAMED \ --add-opens java.base/java.utilALL-UNNAMED \ --add-opens java.base/java.util.concurrentALL-UNNAMED \ --add-opens java.base/sun.nio.chALL-UNNAMED \ --add-opens java.management/javax.managementALL-UNNAMED \ -Dfile.encodingUTF-8 \ -Xms512m -Xmx1024m java $JAVA_OPTS -jar my-application.jar $6. 常见问题排查与实战技巧实录在实际操作中你可能会遇到一些“坑”。以下是我总结的常见问题及解决方法。6.1 问题一参数添加了但错误依旧可能原因及排查参数位置错误最可能的原因。确保--add-opens参数在java命令中位于-jar或主类名之前。在 IDE 中确认是加在“VM 参数”而不是“程序参数”里。包名或模块名拼写错误仔细检查。java.base不是java.basjava.lang不是java.lang.*。目标模块ALL-UNNAMED必须全大写。需要打开的包不止一个错误堆栈只显示了第一个撞墙的访问。解决了第一个--add-opens后可能还会遇到第二个、第三个来自不同包的访问错误。需要耐心地逐一解决。使用--illegal-accesswarn可以一次性看到所有警告。嵌套的模块依赖有时真正进行反射操作的代码在一个深层依赖的库中而这个库又依赖另一个库。你需要确保--add-opens是向最终执行反射操作的代码所在的模块通常是ALL-UNNAMED开放的。这种情况比较少见但可以通过分析堆栈最底层的类加载器信息来辅助判断。6.2 问题二在 Spring Boot 或 Tomcat 等容器中运行这些容器本身也是 Java 应用它们会用自己的类加载器加载你的应用。Spring Boot Executable Jar直接使用java -jar运行按场景一配置即可。如果在 IDE 或 Maven 中运行按对应场景配置。传统 WAR 包部署到外置 Tomcat此时 JVM 参数需要加在 Tomcat 的启动脚本中如catalina.sh或setenv.sh中的CATALINA_OPTS或JAVA_OPTS环境变量。# 在 setenv.sh 中 export JAVA_OPTS$JAVA_OPTS --add-opens java.base/java.langALL-UNNAMEDSpring Boot 内嵌 Tomcat按标准 Spring Boot 应用处理参数加在应用启动命令上。6.3 问题三如何系统性地为大型老项目收集所有需要的--add-opens参数对于有几十上百个依赖的大型单体应用手动从错误日志收集效率太低。推荐流程使用警告模式扫描在测试环境使用 Java 11或你目标版本之前的版本如15添加-Dspring.main.lazy-initializationtrue如果是Spring应用可减少启动时无关警告和--illegal-accesswarn参数启动应用。执行全面测试运行完整的单元测试、集成测试和主要业务流让代码路径尽可能多地被执行。收集和分析日志将控制台输出的所有WARNING: Illegal reflective access by ...日志收集起来。这些警告会明确告诉你哪个类的哪个方法试图打开哪个模块的哪个包。去重和整理用文本处理工具如grep,awk或写个小脚本从警告信息中提取出唯一的模块/包对。例如从警告信息module java.base does not “opens” java.lang to unnamed module中提取java.base/java.lang。生成参数列表将去重后的列表转化为--add-opens参数。可以先全部设置为对ALL-UNNAMED开放。验证使用收集到的参数列表在 Java 16 环境默认--illegal-accessdeny下启动应用确保不再报错。6.4 一个综合性的参数列表参考经过多个项目实践以下是一些非常常见的、需要为未模块化老应用打开的包。注意这只是一个参考起点务必根据自己项目的错误日志进行增删。# 基础核心模块反射访问 --add-opens java.base/java.langALL-UNNAMED --add-opens java.base/java.lang.reflectALL-UNNAMED --add-opens java.base/java.ioALL-UNNAMED --add-opens java.base/java.utilALL-UNNAMED --add-opens java.base/java.util.concurrentALL-UNNAMED --add-opens java.base/java.netALL-UNNAMED --add-opens java.base/java.nioALL-UNNAMED --add-opens java.base/sun.nio.chALL-UNNAMED # 常用于NIO相关库 --add-opens java.base/sun.security.x509ALL-UNNAMED # 常用于SSL/证书处理 # XML处理相关 --add-opens java.xml/com.sun.org.apache.xerces.internal.parsersALL-UNNAMED # 管理扩展相关 --add-opens java.management/javax.managementALL-UNNAMED --add-opens jdk.management/com.sun.management.internalALL-UNNAMED # 本地化相关 --add-opens java.base/sun.util.localeALL-UNNAMED # 序列化/反射增强 --add-opens java.base/java.lang.invokeALL-UNNAMED # 常用于Lambda表达式或MethodHandle最后我的个人体会是处理--add-opens问题是一个典型的“旧世界”与“新世界”的碰撞。它既是迁移的阵痛也是一个契机促使我们去审视和升级技术栈。把每次解决这类问题都当作一次清理技术债务的机会长远来看会让你的应用更健壮、更可持续。对于新启动的项目强烈建议从开始就考虑模块化或者至少使用 LTS 版本的 Java 并保持依赖库的更新这样可以最大程度避免在未来陷入被动。

相关新闻

从RAG、MCP到完整Agent链路:AI应用落地的系统化构建指南

从RAG、MCP到完整Agent链路:AI应用落地的系统化构建指南

1. 项目概述:一个AI从业者的自白与困境“我能解释 RAG、MCP 和 Eval,却画不出一条完整的 Agent 链路。” 这句话最近在我脑子里反复出现,像一句魔咒。作为一个在AI应用层折腾了快十年的老码农,我发现自己陷入了一个尴尬的境地&…

2026/10/20 14:29:49 阅读更多 →
从Spring Boot配置中心实战到微服务架构:如何主动“摸到感觉”

从Spring Boot配置中心实战到微服务架构:如何主动“摸到感觉”

最近在技术社区看到一个很有意思的现象:很多开发者,尤其是刚接触一个新框架或复杂系统的朋友,常常会陷入一种“混沌期”。他们看了很多教程,敲了不少代码,但总觉得知识是散的,像一堆拼图碎片,无…

2026/10/20 17:46:04 阅读更多 →
Windows安装Ubuntu Server 22.04:零基础搭建Linux学习环境

Windows安装Ubuntu Server 22.04:零基础搭建Linux学习环境

1. 项目概述:为什么要在Windows上安装Ubuntu Server? 如果你是一名刚接触Linux的Windows用户,看到“Ubuntu Server”这个词可能会有点发怵。服务器?听起来像是数据中心里那些嗡嗡作响的大家伙,命令行界面黑漆漆的&…

2026/10/20 17:45:58 阅读更多 →

最新新闻

51单片机DS18B20温度采集与NRF905无线传输实战

51单片机DS18B20温度采集与NRF905无线传输实战

简介:这是一套面向单片机爱好者、电子类专业学生与DIY玩家的温度采集与无线传输实践方案,基于51单片机搭配NRF905无线模块,解决短距离温度数据采集与无线收发的问题,适合具备一定电子技术基础、能看懂基础电路图并了解C语言设计原…

2026/10/21 3:09:09 阅读更多 →
YOLOv8/YOLO26目标检测实战:从环境搭建到模型部署完整指南

YOLOv8/YOLO26目标检测实战:从环境搭建到模型部署完整指南

作为一个前前后后用YOLO折腾过不止一个项目的人,我太清楚新手第一次接触YOLO时那种“明明照着教程一步步点,怎么到我这就疯狂报错”的无助感了。这个标题里说的“全网最稳”,其实并不是空话——它邀请你走的,是一条我踩了无数坑之…

2026/10/21 3:09:09 阅读更多 →
DeepSeek Harness 实操:从零跑通智能体框架,25 分钟搭好 Web 界面与第一个插件

DeepSeek Harness 实操:从零跑通智能体框架,25 分钟搭好 Web 界面与第一个插件

DeepSeek Harness 实操:从零跑通智能体框架,25 分钟搭好 Web 界面与第一个插件 【免费下载链接】deepseek-harness DeepSeek Harness: Everything is a Plugin. 项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness DeepSeek Harness(dsh)是 DeepSeek 开源的…

2026/10/21 3:09:09 阅读更多 →
数学建模竞赛真题解读与源码实战:从模型构建到论文输出全链路

数学建模竞赛真题解读与源码实战:从模型构建到论文输出全链路

简介:一套面向高校数学建模竞赛的完整培训材料,涵盖基础理论、建模方法、真题解析与源代码实现,适合从入门到备赛冲刺的各阶段学生。压缩包共61个文件,约2.02MB,以30个MATLAB脚本、16个Word文档和6个Excel表格为主&…

2026/10/21 3:09:09 阅读更多 →
高职院校智能体应用生态建设:OpenClaw落地实战指南

高职院校智能体应用生态建设:OpenClaw落地实战指南

1. 项目概述:为什么要研究OpenClaw在高职院校的落地先说结论:OpenClaw这个项目本身不是什么新概念,它本质上是一套开源的多智能体编排框架。我接触它是在一次校内数字化转型研讨会上,某高校信息中心的某老师提到他们正在试水智能体…

2026/10/21 3:09:09 阅读更多 →
数据获取与处理实战:从数据源选择到数据清洗的完整指南

数据获取与处理实战:从数据源选择到数据清洗的完整指南

这几年做数据相关的工作,被问得最多的一个问题是:“我该从哪儿拿数据?拿到手之后又该怎么处理?”说实话,大多数人在第一步就卡住了,要么不知道怎么稳定地拿到数据,要么千辛万苦拿到一份Excel&am…

2026/10/21 3:08:09 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →