来自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)
有人可以解释为什么只有没有类型才有效吗?
没有类型,final val就像文字常量一样 - 标识符在编译时被其值替换.对于类型,它成为对某些存储的东西的引用,这些东西不能用于注释.
这在规范的4.1节中定义:
形式是常量值定义
Run Code Online (Sandbox Code Playgroud)final val x = e其中e是常数表达式(§6.24).必须存在最终修饰符,并且不能给出类型注释.对常量值x的引用本身被视为常量表达式; 在生成的代码中,它们被定义的右侧e替换.
这是在Scala中获得真正命名常量的唯一方法.它们具有性能优势,它们确实不会发生变异(甚至final val可以通过反射改变类型),当然,它们也可以用于注释.