scala注释参数需要是常量,但最终的val不能成功

时间:2017-12-08 10:11:55

标签: scala compiler-errors annotations

在此代码段中,

@SwaggerDefinition(...authorizationUrl = 
SecurityConstants.authorizationUrl)

并且给出了

final object SecurityConstants {
  final val authorizationUrl: String =..
}

(两场决赛中只有一场应该没问题,但仍然如此) 我期待/希望这可以用2.12.3进行编译但是它给出了 "注释参数需要是常量;发现:SecurityConstants.authorizationUrl [error] authorizationUrl = SecurityConstants.authorizationUrl,"

在注释中调用Java静态方法System.getenv(" a")会带来相同的错误,即

@SwaggerDefinition(...authorizationUrl = System.getenv("a"))

请帮忙, Nicu M

2 个答案:

答案 0 :(得分:9)

在两个条件下,

final val引用可以用作Java注释参数:

  1. 分配给final val的值必须是文字。
  2. 您必须明确指定final val的类型。
  3. 所以,这将有效:

    final val authorizationUrl = "http://something.com"
    

    但这些工作:

    final val authorizationUrl = "http://something.com".trim
    final val authorizationUrl: String = "http://something.com"
    

    条件号。 2可能看起来特别奇怪,但编译器需要在内部保留final val所持有的信息,而不仅仅是String,而是一些特定的文字字符串值。

答案 1 :(得分:1)

..背后的内容非常重要
final val authorizationUrl: String =..

在Scala和Java中,注释参数必须是 编译时 常量,而不仅仅是“最终”。所以System.getenv("a")(或任何其他函数调用)直接或通过中间val将不会这样做,因为这不是编译时常量。这样做是因为注释被设计为在编译时是内省的,即如果你只有一个.class文件,你必须能够获得注释的所有字段的值。因此编译器必须在编译时知道所有值。

<强>更新

实际上Swagger本身依赖于编译时内省。那么您对System.getenv电话的期望是什么? Swagger应该为这样的注释生成什么规范?为什么你需要它呢? AFAIU如果您有多个环境,则应将生产的URL(即外部用户访问的URL)放入定义中。