将显式类型添加到val可防止val在注释中用作常量

sca*_*eno 9 annotations scala

来自REPL:

scala> final val x = "x"
x: java.lang.String("x") = x

scala> @javax.persistence.Table(name = x) case class foo()
defined class foo

scala> final val x:java.lang.String = "x"
x: java.lang.String = x

scala> @javax.persistence.Table(name = x) case class foo()
<console>:6: error: annotation argument needs to be a constant; found: x
       @javax.persistence.Table(name = x) case class foo()
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么只有没有类型才有效吗?

Dan*_*ral 8

没有类型,final val就像文字常量一样 - 标识符在编译时被其值替换.对于类型,它成为对某些存储的东西的引用,这些东西不能用于注释.

这在规范的4.1节中定义:

形式是常量值定义

final val x = e
Run Code Online (Sandbox Code Playgroud)

其中e是常数表达式(§6.24).必须存在最终修饰符,并且不能给出类型注释.对常量值x的引用本身被视为常量表达式; 在生成的代码中,它们被定义的右侧e替换.

这是在Scala中获得真正命名常量的唯一方法.它们具有性能优势,它们确实不会发生变异(甚至final val可以通过反射改变类型),当然,它们也可以用于注释.