映射值应该在常量中声明还是作为枚举声明?

2022-09-04 01:11:10

我看到这分散在整个代码库中:

@RequestMapping(value = "myValue")

我更喜欢使用这样的东西:

@RequestMapping(value = Constants.myValue)

它似乎使用内部的实际字符串值而不是常量来中断DRY。但这是良好的代码实践吗?我应该改用枚举吗?我可能需要在代码库中的其他地方使用。@RequestMappingConstants.myValue


答案 1

我应该改用枚举吗?

你不能。注释变量必须是编译时常量。枚举和字符串文本都是,但您不能创建字符串且需要字符串的枚举(如果您的枚举具有返回字符串或字符串字段的方法,则不是编译时常量)。由于存在多轮注释处理,因此当常量位于另一个类中时,它确实有效。@RequestMapping

也就是说:是的,我会说使用专用的常量类(也许是几个,对于不同类型的常量)是一个很好的做法,只要常量a)不在具有注释的同一编译单元中定义并且b)在声明中初始化(而不是静态初始值设定项块),它就适用于注释。

下面是一个示例:

控制器

@Controller @RequestMapping(value = Mappings.CUSTOMER_PAGE)
public class CustomerPageController{
    // methods here
}

常量类

public static final class Mappings{
    private Mappings(){}
    public static final String CUSTOMER_PAGE = "path/to/customer/page"
    // more constants
}

以下是一些不起作用的版本:

a)

@Controller @RequestMapping(value = CUSTOMER_PAGE)
public class CustomerPageController{
    private static final String CUSTOMER_PAGE = "path/to/customer/page";
}

这不会编译,因为批注引用它所批注的类中的常量。这不起作用,因为在编译期间,注释在代码的其余部分之前在单独的一轮中处理,而类需要已经处理注释以进行编译(即注释和常量之间存在循环依赖关系)

b)

public static final class Mappings{
    private Mappings(){}
    public static final String CUSTOMER_PAGE;
    static{
        CUSTOMER_PAGE = "path/to/customer/page"
    }

    // more constants
}

虽然这是一个静态的最终字段,但它不是编译时常量,因此它不能用作注释参数


答案 2