让注解在编译时“写代码”——自动生成 Builder
一、又遇到了新麻烦订单对象需要经常被创建但它的构造方法参数很多new Order(O001, 手机, new BigDecimal(5999), 1, new Date(), 内部备注); // 谁能记得住参数顺序极易写错。我们想用建造者模式Builder但为每个类手写 Builder 又很枯燥。能不能在订单类上贴一个 Builder 注解编译时自动生成 Builder 代码这就是 Lombok 这种神器的原理我们现在自己实现一个极简版。二、编译时注解处理是什么上一节我们的 ExcelColumn 保留到运行时通过反射读取会有轻微的性能损耗。这次我们要用的注解生命周期在编译时SOURCE它不进入 .class 文件而是由注解处理器在编译阶段读到然后生成新的 .java 源文件之后再一起编译成 .class。整个流程源码 注解 - 注解处理器生成新源码 - javac 编译所有源码 - class文件三、第一步定义 Builder 注解这次保留策略用 SOURCE因为运行时不需要它。import java.lang.annotation.*; Target(ElementType.TYPE) // 贴在类上 Retention(RetentionPolicy.SOURCE) // 编译时就被丢弃 public interface Builder { }四、第二步实现注解处理器核心处理器需要在 javac 编译时被调用。我们创建一个处理器类并让它能识别 Builder。import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.*; import javax.lang.model.type.TypeMirror; import javax.tools.JavaFileObject; import java.io.IOException; import java.io.PrintWriter; import java.util.*; // 告诉javac这个处理器能处理哪些注解 SupportedAnnotationTypes(Builder) SupportedSourceVersion(SourceVersion.RELEASE_8) public class BuilderProcessor extends AbstractProcessor { Override public boolean process(Set? extends TypeElement annotations, RoundEnvironment roundEnv) { // 遍历每一个被Builder标注的元素类 for (Element element : roundEnv.getElementsAnnotatedWith(Builder.class)) { if (element.getKind() ! ElementKind.CLASS) { continue; // 只处理类 } TypeElement classElement (TypeElement) element; String packageName processingEnv.getElementUtils().getPackageOf(classElement).getQualifiedName().toString(); String className classElement.getSimpleName().toString(); String builderClassName className Builder; // 收集类中所有字段包括私有的 getter 或直接访问字段这里简化我们约定该类有标准的getter方法或者我们直接使用字段名生成setter风格的Builder方法 ListVariableElement fields new ArrayList(); for (Element enclosed : classElement.getEnclosedElements()) { if (enclosed.getKind() ElementKind.FIELD) { fields.add((VariableElement) enclosed); } } // 生成Builder类的源代码 StringBuilder builderCode new StringBuilder(); builderCode.append(package ).append(packageName).append(;\n\n); builderCode.append(public class ).append(builderClassName).append( {\n); // 字段和对应的set方法 for (VariableElement field : fields) { String fieldName field.getSimpleName().toString(); String fieldType field.asType().toString(); builderCode.append( private ).append(fieldType).append( ).append(fieldName).append(;\n); builderCode.append( public ).append(builderClassName).append( ).append(fieldName).append(().append(fieldType).append( ).append(fieldName).append() {\n); builderCode.append( this.).append(fieldName).append( ).append(fieldName).append(;\n); builderCode.append( return this;\n); builderCode.append( }\n); } // build方法 builderCode.append( public ).append(className).append( build() {\n); builderCode.append( ).append(className).append( obj new ).append(className).append(();\n); for (VariableElement field : fields) { String fieldName field.getSimpleName().toString(); // 为了简单我们假设目标类有对应的set方法如setOrderId String setter set Character.toUpperCase(fieldName.charAt(0)) fieldName.substring(1); builderCode.append( obj.).append(setter).append((this.).append(fieldName).append();\n); } builderCode.append( return obj;\n); builderCode.append( }\n); builderCode.append(}\n); // 写出生成的源文件 try { JavaFileObject sourceFile processingEnv.getFiler().createSourceFile(packageName . builderClassName); try (PrintWriter out new PrintWriter(sourceFile.openWriter())) { out.println(builderCode.toString()); } } catch (IOException e) { e.printStackTrace(); } } return true; } }这个处理器做的事扫描到标记 Builder 的类。提取该类的所有字段。生成一个名为 原类名Builder 的类每个字段有一个同名方法返回Builder自身最后 build() 方法里调用原类的 setter 来构造对象。五、第三步配置处理器让它生效用 Maven 编译的话需要在 pom.xml 中配置注解处理器路径或者在 META-INF/services 里注册。这里用最简单的手动方式演示直接在代码结构里放好处理器然后在编译时指定 -processor 参数或在 IDE 中开启注解处理。假设我们项目结构src/main/java/ com/example/ Order.java (加 Builder 注解) BuilderProcessor.java编译时如果我们让 javac 运行处理器就会自动在 build/generated-sources/ 之类的目录下生成 OrderBuilder.java。四、第四步使用时发生了什么我们给 Order 类加上 BuilderBuilder public class Order { private String orderId; private String productName; // ... 字段、setter和getter }编译后自动生成的 OrderBuilder.java 大概是这个样子package com.example; public class OrderBuilder { private String orderId; private String productName; // 其他字段... public OrderBuilder orderId(String orderId) { this.orderId orderId; return this; } public OrderBuilder productName(String productName) { this.productName productName; return this; } // 其他字段的类似方法... public Order build() { Order obj new Order(); obj.setOrderId(this.orderId); obj.setProductName(this.productName); // ... return obj; } }程序员就可以直接这么写Order order new OrderBuilder() .orderId(O123) .productName(机械键盘) .price(new BigDecimal(299)) .quantity(2) .build();你感受一下这个变化不用再记构造方法参数顺序。代码像写自然语言一样流畅。OrderBuilder 完全由注解在编译时自动生成你零手写成本。注解真正的威力在于它把原本需要写死在代码里的“元数据”和“逻辑模板”提取出来让框架或编译器帮我们自动生成代码或自动执行逻辑。无论是运行时读注解的反射框架还是编译时代码生成器本质上都是程序读程序让开发效率成倍提升。

相关新闻

Apollo Federation性能优化:让你的数据图响应速度提升300%

Apollo Federation性能优化:让你的数据图响应速度提升300%

Apollo Federation性能优化:让你的数据图响应速度提升300% 【免费下载链接】federation 🌐 Build and scale a single data graph across multiple services with Apollos federation gateway. 项目地址: https://gitcode.com/gh_mirrors/feder/feder…

2026/7/26 22:33:47 阅读更多 →
企业级RAG系统架构设计与实践指南

企业级RAG系统架构设计与实践指南

1. 企业级RAG系统概述RAG(Retrieval-Augmented Generation)技术正在重塑企业知识管理的格局。这种结合信息检索与文本生成的技术架构,让AI系统既能像专业研究员一样精准获取知识,又能像资深顾问一样流畅输出见解。我在金融、医疗、…

2026/7/26 22:33:47 阅读更多 →
Jellium Desktop媒体格式兼容性测试:检查文件是否可播放的完整指南

Jellium Desktop媒体格式兼容性测试:检查文件是否可播放的完整指南

Jellium Desktop媒体格式兼容性测试:检查文件是否可播放的完整指南 【免费下载链接】jellium-desktop An unofficial desktop client for Jellyfin 项目地址: https://gitcode.com/GitHub_Trending/je/jellium-desktop Jellium Desktop是一款强大的非官方Jel…

2026/7/26 22:32:47 阅读更多 →

最新新闻

Qwen-3与Unsloth轻量化大模型微调实战指南

Qwen-3与Unsloth轻量化大模型微调实战指南

1. 为什么选择 Qwen-3 和 Unsloth 进行微调?在开始动手之前,我们需要先理解为什么这个组合特别适合新手和资源有限的开发者。传统的大模型微调往往需要昂贵的硬件设备和复杂的配置过程,而 Qwen-3 和 Unsloth 的组合完美解决了这些问题。1.1 算…

2026/7/26 22:54:57 阅读更多 →
从尺寸竞赛到时空协同:贾子时空缩微定律(KSTS, Kucius Law of Space-Time Scaling)与全球人工智能研究范式的系统性重构

从尺寸竞赛到时空协同:贾子时空缩微定律(KSTS, Kucius Law of Space-Time Scaling)与全球人工智能研究范式的系统性重构

从尺寸竞赛到时空协同:贾子时空缩微定律(KSTS, Kucius Law of Space-Time Scaling)与全球人工智能研究范式的系统性重构摘要全球人工智能产业正处于历史性的范式转换关口。以晶体管几何缩微为核心的摩尔定律在逼近物理极限后持续失效&#xf…

2026/7/26 22:54:57 阅读更多 →
光伏高渗透配电网电压概率预测与调控技术

光伏高渗透配电网电压概率预测与调控技术

1. 研究背景与核心问题新能源革命正在重塑全球电力系统格局,光伏发电作为清洁能源的主力军,近年来在配电系统中的渗透率呈现指数级增长。以中国为例,2022年分布式光伏新增装机容量达到51.1GW,占当年光伏新增装机的58%,…

2026/7/26 22:54:57 阅读更多 →
Windows 环境 OCCT 8.0 编译构建及与 Qt6 项目集成

Windows 环境 OCCT 8.0 编译构建及与 Qt6 项目集成

一、所需工具 工具版本说明Visual Studio2022 (Professional)编译器CMake3.31.12构建工具Qt6.11用于后续界面开发注意:安装过程简单,此处不再赘述。工具包 Qt 镜像安装(推荐使用国内源加速): 在 qt-online-installer-…

2026/7/26 22:54:57 阅读更多 →
基于DirectX Raytracing的实时光线追踪实践:从DXR API到渲染管线搭建

基于DirectX Raytracing的实时光线追踪实践:从DXR API到渲染管线搭建

1. 项目概述:从光栅化到光线追踪的视觉革命如果你是一名图形程序员,或者对游戏画面、电影特效背后的技术着迷,那么“光线追踪”这个词对你来说一定不陌生。它早已不是实验室里的概念,而是从《赛博朋克2077》到《我的世界》RTX版&a…

2026/7/26 22:54:57 阅读更多 →
OBS面部追踪插件:让你的直播镜头自动跟随人脸移动

OBS面部追踪插件:让你的直播镜头自动跟随人脸移动

OBS面部追踪插件:让你的直播镜头自动跟随人脸移动 【免费下载链接】obs-face-tracker Face tracking plugin for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-face-tracker 在直播、在线教学或视频录制时,你是否经常需要手动调整…

2026/7/26 22:53:56 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻