关于阿里java开发规范中枚举类型字段必须有注释的思考

本文探讨了Java开发中遵循阿里巴巴代码规范,关于枚举值注释的要求。作者分享了一次代码审查中遇到的冲突,即扩展枚举类与注释重复的问题,并最终决定为了提高代码可读性和一致性,选择遵循规范,即使这意味着注释的冗余。
摘要由CSDN通过智能技术生成

背景

今天使用AlibabaJavaCodeGuidelines插件进行代码规范检查时,有一类关于枚举值注释的错误报了出来:

在阿里巴巴java开发规范中,是有下面这条规范
【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途。

分析

这条规范很好理解。
对于枚举常量来说,注释是非常关键的。因为枚举常量的命名虽然应该尽可能地清晰和具有描述性,但有时候仅仅通过名称可能仍然无法完全准确地理解其背后的含义和用途。特别是在复杂系统中,枚举常量可能涉及多个业务逻辑和规则,没有注释的话,其他开发者可能需要花费额外的时间和精力去揣测和理解。

但是吧,当初我写代码的时候为什么没加注释呢?

原因也很简单,在我的系统设计中,将所有的异常,使用了枚举类,扩展了一个message属性,用于系统抛出异常后,给系统用户一个友好的提示,也就是对应的中文描述信息。

@Getter
public enum AppExceptionEnum implements ExceptionInterface {

    APP_CODE_OR_SECRET_ERROR("应用编码有误或密钥错误"),
    APP_CODE_NOT_EXIST("应用编码不存在"),
    ;
    private String message;

    AppExceptionEnum(String message) {
        this.message = message;
    }

}

这种情况下,这个枚举值什么含义,message属性中存放的中文描述足以表达清楚。

思考

如果按照阿里java代码规范要求,则需要调整为以下方式:

@Getter
public enum AppExceptionEnum implements ExceptionInterface {

    /**
     * 应用编码有误或密钥错误
     */
    APP_CODE_OR_SECRET_ERROR("应用编码有误或密钥错误"),
    /**
     * 应用编码不存在
     */
    APP_CODE_NOT_EXIST("应用编码不存在"),
    ;
    private String message;

    AppExceptionEnum(String message) {
        this.message = message;
    }
}

这样就存在一个明显的问题,重复,注释与中文描述是重复的,新增的话,需要来两遍,修改的话,也要改两遍,并且需要同步,容易出现不一致的问题。

那么,这条规范是不是比较适合下面这种比较原始的枚举类,只有一个编码,没有进行扩展。

/**
 * 接口服务执行结果
 * @author wqliu
 */
@Getter
public enum ApiServiceExecuteResultEnum {

    /**
     * 成功
     */
    SUCCESS,
    /**
     * 错误
     */
    ERROR
    ;

}

而对于我这种进行了扩展,有message属性来表达枚举常量含义的情况下,是不是不加注释更合理一些呢?

注:我们可以在枚举类上加上一句@SuppressWarnings(“AlibabaEnumConstantsMustHaveComment”),这样进行代码规范检查的时候就不会再提示错误。

认真思考了下,还是遵循规范更优一些,主要是以下两方面:
1.如不加注释,在使用枚举值的地方,鼠标悬停并不会提示这个枚举值的含义,降低代码的可读性
2.对于重复问题,考虑到枚举值是常量,这些常量值的变动频率通常极低,新增和修改都比较少,重复两遍的问题,倒也可以接受

最后,回看了阿里规范的示例,也是重复了两遍。

   public enum TestEnum {
        /**
         * agree
         */
        agree("agree"),
        /**
         * reject
         */
        reject("reject");
        
        private String action;
    
        TestEnum(String action) {
            this.action = action;
        }
    
        public String getAction() {
            return action;
        }
    }

结论

最终的结论,这种情况下,遵循规范是最优的选择,即需要给枚举常量加注释。

附录

阿里巴巴Java开发手册「2023最新黄山版」是阿里巴巴技术团队的集体智慧结晶和内部经验的总结。该手册以Java开发者为中心视角,划分为编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约七个维度,再根据内容特征细分成若干二级子目录。此外,依据约束力强弱及故障敏感性,规约依次分为“强制”、“推荐”、“参考”三大类。在手册中,“说明”对规约做了适当扩展和解释,“正例”提倡什么样的编码和实现方式,“反例”则指出需要提防的雷区以及真实的错误案例。

该版本经历了多次打磨和完善,代表了阿里巴巴在Java开发方面的最佳实践和经验。学习和遵循这份手册可以帮助Java开发者提高代码质量、减少错误,并提升整体的开发效率。

请注意,随着技术的不断发展和阿里巴巴业务的变化,开发手册也可能会有所更新。因此,建议开发者在使用过程中,关注手册的最新版本,以便获取最新的开发规范和最佳实践。

此外,由于手册涉及的是技术规范和最佳实践,因此在遵循手册的同时,也需要结合具体的项目需求和技术栈进行灵活应用。在实际开发中,遇到问题时可以查阅手册以获取指导,但也需要根据实际情况进行判断和调整。

最后,请注意,虽然该手册是阿里巴巴的官方文档,但开发者在使用过程中仍需谨慎对待,并结合自身项目的实际情况进行选择和应用。对于手册中可能存在的不明确或有疑问的部分,建议与团队成员或技术专家进行讨论和确认,以确保项目的顺利进行。

Java,可以通过反射机制获取枚举类型。以下是获取Java所有枚举类型的示例代码: ```java import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class EnumExporter { public static void main(String[] args) { Class<?>[] classes = { MyEnum.class }; // 将要导出枚举类型的类 for (Class<?> cls : classes) { System.out.println("Enum Type: " + cls.getName()); if (cls.isEnum()) { Field[] fields = cls.getDeclaredFields(); for (Field field : fields) { if (Modifier.isStatic(field.getModifiers())) { System.out.println("Enum Value: " + field.getName()); } } } System.out.println(); } } enum MyEnum { VALUE1, VALUE2, VALUE3 } } ``` 在这个例子,我们定义了一个 `EnumExporter` 类,它包含一个名为 `main` 的方法,该方法将要导出枚举类型的类作为参数,并使用反射机制获取该类的所有枚举类型。 在 `main` 方法,我们定义了一个 `MyEnum` 枚举类型的类,并将其作为参数传递给 `EnumExporter` 类的实例。然后,我们使用 `Class.isEnum()` 方法检查该类是否是枚举类型,如果是,则使用 `Class.getDeclaredFields()` 方法获取该类的所有字段,并在每个字段上使用 `Modifier.isStatic()` 方法检查该字段是否是静态字段(即枚举)。如果是,则输出该字段的名称。 运行此程序将输出以下内容: ``` Enum Type: EnumExporter$MyEnum Enum Value: VALUE1 Enum Value: VALUE2 Enum Value: VALUE3 ``` 这表明 `MyEnum` 是一个枚举类型,并且它有三个枚举:`VALUE1`、`VALUE2` 和 `VALUE3`。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学海无涯,行者无疆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值