来自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()
有人可以解释为什么这只能在没有类型的情况下起作用吗?
答案 0 :(得分:8)
如果没有类型,final val
就像一个文字常量 - 标识符在编译时被其值替换。对于类型,它成为对某个地方存储的东西的引用,这些东西不能用于注释。
这在规范的4.1节中定义:
常量值定义的格式为
final val x = e
其中e是常数表达式(§6.24)。最终修饰符必须是 目前并没有给出类型注释。参考文献 常量值x本身被视为常量表达式;在 生成的代码由定义的右侧替换 方e。
这是在Scala中获得真正命名常量的唯一方法。它们具有性能优势,它们确实不会发生变异(即使可以通过反射改变类型的final val
),当然,它们也可以用于注释。