Java 方法参数默认值新方案:使用DefArgs!

DefArgs

一个 Java 注解处理器,通过 @DefaultValue@Omittable 注解为方法参数提供默认值支持和重载方法生成。

快速开始

在 Maven 项目中添加依赖(查看最新版本):

xml 复制代码
<dependency>
    <groupId>io.github.thirty30ww</groupId>
    <artifactId>defargs</artifactId>
    <version>LATEST</version> <!-- 请替换为上方链接或者徽章显示的最新版本 -->
</dependency>

使用方法

具体类使用 @DefaultValue

为具体类的方法参数添加 @DefaultValue 注解,编译器会自动生成带默认值的重载方法。

java 复制代码
public class UserService {
    public void createUser(
        String name,
        @DefaultValue("18") int age,
        @DefaultValue("true") boolean active
    ) {
        // 实现逻辑
    }
}

编译后自动生成:

java 复制代码
// 生成的重载方法 1
public void createUser(String name, int age) {
    createUser(name, age, true);
}

// 生成的重载方法 2  
public void createUser(String name) {
    createUser(name, 18, true);
}

现在你可以用更简洁的方式调用:

java 复制代码
service.createUser("Alice");              // 使用全部默认值
service.createUser("Bob", 25);            // 部分使用默认值
service.createUser("Charlie", 30, false); // 不使用默认值

接口和抽象类使用 @Omittable

对于接口或抽象类的抽象方法,使用 @Omittable 注解标记可省略的参数。编译器会生成对应的抽象重载方法。

java 复制代码
public interface UserRepository {
    User findUser(
        String name,
        @Omittable int age,
        @Omittable boolean active
    );
}

编译后自动生成抽象重载方法:

java 复制代码
// 生成的抽象重载方法 1
User findUser(String name, int age);

// 生成的抽象重载方法 2
User findUser(String name);

在实现类中,使用 @DefaultValue 提供具体的默认值:

java 复制代码
public class UserRepositoryImpl implements UserRepository {
    @Override
    public User findUser(
        String name,
        @DefaultValue("18") int age,
        @DefaultValue("true") boolean active
    ) {
        // 实现逻辑
        return new User(name, age, active);
    }
    // 编译器会自动为实现类生成带默认值的重载方法
}

工作原理

DefArgs 在编译时通过 Java 注解处理器生成重载方法,不依赖反射,对运行时性能零影响。

注解处理器会扫描所有带 @DefaultValue@Omittable 注解的方法参数,并在编译时直接修改 AST(抽象语法树),将生成的重载方法添加到同一个类或接口中。这意味着生成的代码与手写代码完全相同,没有任何性能开销。

注意事项

1. 注解使用规则

  • @DefaultValue:只能用于具体方法(有方法体的方法)
  • @Omittable:只能用于抽象方法(接口或抽象类的抽象方法)
  • 同一个参数不能同时使用两个注解
java 复制代码
// 正确:具体方法使用 @DefaultValue
public void method(int a, @DefaultValue("1") int b) { }

// 正确:抽象方法使用 @Omittable
abstract void method(int a, @Omittable int b);

// 错误:抽象方法不能使用 @DefaultValue
abstract void method(int a, @DefaultValue("1") int b);

// 错误:具体方法不能使用 @Omittable
public void method(int a, @Omittable int b) { }

2. 可省略参数必须从右向左连续

java 复制代码
// 支持
void method(int a, @DefaultValue("1") int b, @DefaultValue("2") int c)

// 不支持
void method(@DefaultValue("1") int a, int b, @DefaultValue("2") int c)

3. 不要手动定义冲突的重载方法

如果手动定义了与生成方法签名相同的重载方法,编译时会报错:

java 复制代码
public int test(int a, @DefaultValue("2") int b) {
    return a + b;
}

public int test(int a) {  // 编译错误:此方法会自动生成
    return a + 1;
}

编译错误信息:

scss 复制代码
【DefaultValue】 已在类 com.example.MyClass 中定义了方法 test(int)

4. 支持的类型

@DefaultValue 注解目前支持以下类型的默认值:

  • 基本类型byteshortintlongfloatdoublebooleanchar
  • 包装类型ByteShortIntegerLongFloatDoubleBooleanCharacter
  • 字符串类型String

注意:默认值必须是字符串字面量,编译器会自动转换为对应类型的值。

@Omittable 可以用于任何类型的参数,包括基本类型、包装类型和字符串类型。

IntelliJ IDEA 支持

如果你使用 IntelliJ IDEA,建议安装配套的 defargs-intellij-plugin ,以获得更好的开发体验。插件会让 IDEA 识别这些生成的重载方法,消除错误提示并提供代码补全。

构建项目

bash 复制代码
mvnw clean install

协议

MIT License

相关推荐
Mr -老鬼4 分钟前
Rust适合干什么?为什么需要Rust?
开发语言·后端·rust
予枫的编程笔记7 分钟前
【Java集合】深入浅出 Java HashMap:从链表到红黑树的“进化”之路
java·开发语言·数据结构·人工智能·链表·哈希算法
ohoy13 分钟前
RedisTemplate 使用之Set
java·开发语言·redis
mjhcsp13 分钟前
C++ 后缀数组(SA):原理、实现与应用全解析
java·开发语言·c++·后缀数组sa
123445221 分钟前
Agent入门实战-一个题目生成Agent
人工智能·后端
IT_陈寒23 分钟前
Java性能调优实战:5个被低估却提升30%效率的JVM参数
前端·人工智能·后端
快手技术24 分钟前
AAAI 2026|全面发力!快手斩获 3 篇 Oral,12 篇论文入选!
前端·后端·算法
颜酱26 分钟前
前端算法必备:滑动窗口从入门到很熟练(最长/最短/计数三大类型)
前端·后端·算法
8***f39527 分钟前
Spring容器初始化扩展点:ApplicationContextInitializer
java·后端·spring
用户2986985301429 分钟前
C#: 如何自动化创建Word可填写表单,告别手动填写时代
后端·c#·.net