为什么注释属性的值应该是常量表达式?

我有以下代码

@UIUnitTimeout(8*60*1000) // works @UIUnitTimeout(TimeUnit.MINUTES.toMillis(8)) // does not work 

我知道根据JLS,只允许常量表达式作为注释属性的值。 但为什么? 如果数据类型匹配,为什么还不够? 如果要在运行时评估表达式,是否有任何可能出错的地方? 每个规范都有逻辑推理吗?

注释类似于类型扩展或关于类型的元数据。

因为java是一种静态类型语言(意味着类型在编译时是已知的),所以在编译时也可以知道注释属性数据(元数据) – 您正在定义/声明有关注释(扩展)的数据。

作为一个纯粹实用的点,对于注释处理 (编译时(可选)步骤), 必须在编译时知道属性数据 – 您尚未到达运行时环境,但您需要属性数据。

注释预处理需要在执行带注释的代码之前知道注释的值。 此外,注释定义本身也是使用@Retention进行分配的,其值为RetentionPolicy (如果未指定,则默认为CLASS)。

因此,有3种不同的“种类”注释,只有那些声明为RUNTIME的注释在程序执行时才可用。 (但它们的值必须是常量,以便在不执行相关代码的情况下保持定义。)

CLASS注释将由编译器记录在类文件中,但在运行时不需要由VM保留。

RUNTIME注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以reflection性地读取它们。

SOURCE注释将被编译器丢弃。