开发者

Adding explicit type to val prevents val from being used as a constant in annotation

From the 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 cl开发者_JAVA百科ass foo()

Can someone explain why this only works without a type?


Without the type, final val acts like a literal constant -- the identifier is replaced by its value at compile time. With the type, it becomes a reference to something stored somewhere, which cannot be used on annotations.

This is defined on section 4.1 of the specification:

A constant value definition is of the form

final val x = e

where e is a constant expression (§6.24). The final modifier must be present and no type annotation may be given. References to the constant value x are themselves treated as constant expressions; in the generated code they are replaced by the definition's right-hand side e.

This is the only way you can get true named constants in Scala. They have performance benefits, they are really guaranteed not to mutate (even a final val with a type can be changed through reflection) and, of course, they can be used in annotations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜