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

相关推荐
czlczl200209251 小时前
告别 try-catch 地狱:Spring Boot 全局异常处理 (GlobalExceptionHandler) 最佳实践
java·spring boot·后端
神奇的程序员6 小时前
从已损坏的备份中拯救数据
运维·后端·前端工程化
Goldn.7 小时前
Java核心技术栈全景解析:从Web开发到AI融合
java· spring boot· 微服务· ai· jvm· maven· hibernate
oden7 小时前
AI服务商切换太麻烦?一个AI Gateway搞定监控、缓存和故障转移(成本降40%)
后端·openai·api
李慕婉学姐8 小时前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
m0_740043738 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
编织幻境的妖8 小时前
SQL查询连续登录用户方法详解
java·数据库·sql
未若君雅裁9 小时前
JVM面试篇总结
java·jvm·面试
kk哥88999 小时前
C++ 对象 核心介绍
java·jvm·c++
招风的黑耳9 小时前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端