如何在子类中覆写@DefaultValue注解以设置不同默认值
可行的解决方案
由于Java本身不支持直接覆写字段的注解(子类字段只能隐藏父类字段,而非覆写),针对你的场景,有以下几种实用方案:
方案1:抽象方法+子类重写(推荐)
把需要自定义注解的字段,在基类中定义为抽象方法,子类通过重写方法并添加自定义注解来实现差异化配置,其他公共字段仍放在基类中。
示例代码:
// 基类BaseDto public abstract class BaseDto { // 公共字段,统一注解 @QueryParam("page") @DefaultValue("1") private Integer page; @QueryParam("size") @DefaultValue("10") private Integer size; // 抽象方法,留给子类自定义注解 public abstract String getSortBy(); } // 子类KeywordsDto public class KeywordsDto extends BaseDto { @Override @QueryParam("sortBy") @DefaultValue("keyword_score") public String getSortBy() { return super.getSortBy(); } // 子类自有字段 @QueryParam("keywords") private String keywords; }
这种方式完全符合Java语法规范,注解解析时能直接识别子类方法上的注解,同时避免了字段重复定义。
方案2:子类重定义字段并覆盖注解
如果更倾向于用字段而非方法,可以在子类中重新定义同名字段,并添加自定义注解。此时需要注意:子类字段会隐藏父类字段,解析注解时要确保优先读取子类的字段注解。
示例代码:
// 基类BaseDto public class BaseDto { @QueryParam("page") @DefaultValue("1") private Integer page; @QueryParam("size") @DefaultValue("10") private Integer size; @QueryParam("sortBy") @DefaultValue("create_time") protected String sortBy; } // 子类KeywordsDto public class KeywordsDto extends BaseDto { // 重定义字段,添加自定义默认值注解 @QueryParam("sortBy") @DefaultValue("keyword_score") private String sortBy; @QueryParam("keywords") private String keywords; // 重写getter/setter,确保操作子类字段 @Override public String getSortBy() { return this.sortBy; } @Override public void setSortBy(String sortBy) { this.sortBy = sortBy; } }
需要配合自定义的注解解析逻辑:反射获取字段时,优先从当前类(子类)查找,找不到再去父类查找,确保子类注解生效。
方案3:自定义可配置注解+解析逻辑封装
如果有多个字段需要自定义默认值,可以封装一层自定义注解,允许子类指定差异化配置,然后在解析工具类中统一处理优先级。
示例代码:
// 自定义注解,支持覆盖默认值 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface OverrideDefaultValues { FieldDefault[] value(); } @interface FieldDefault { String fieldName(); String defaultValue(); } // 基类BaseDto public class BaseDto { @QueryParam("page") @DefaultValue("1") private Integer page; @QueryParam("size") @DefaultValue("10") private Integer size; @QueryParam("sortBy") @DefaultValue("create_time") private String sortBy; } // 子类KeywordsDto @OverrideDefaultValues({ @FieldDefault(fieldName = "sortBy", defaultValue = "keyword_score") }) public class KeywordsDto extends BaseDto { @QueryParam("keywords") private String keywords; }
然后编写注解解析工具类:先读取子类的@OverrideDefaultValues注解,获取字段的自定义默认值;如果没有,则读取基类字段的@DefaultValue注解值。这种方式无需重复定义字段,适合需要自定义多个字段的场景。
内容的提问来源于stack exchange,提问作者Dred
相关产品推荐
相关产品推荐

