paul paul - 1 month ago 8
Scala Question

Usages of Constants in Constructor

It´s most probably a stupid question, I saw an answer already here but seems does not work in my particular case. Here my code

object ProductAdded{
val PRODUCT_NAME:String="productName"
val PRODUCT_PRICE:String="productPrice"
}

class ProductAdded @JsonCreator()(@JsonProperty(PRODUCT_NAME) var productName: String,
@JsonProperty(PRODUCT_PRICE) var productPrice: String) extends Event {


@JsonProperty(PRODUCT_NAME) def getProductName: String = {
productName
}

@JsonProperty(PRODUCT_PRICE) def getProductPrice: String = {
productPrice
}
}


I´m trying to use those constants in the constructor, but when I compile show this error

Error:(12, 49) annotation argument needs to be a constant; found: event.ProductAdded.PRODUCT_NAME
class ProductAdded @JsonCreator()(@JsonProperty(PRODUCT_NAME) var productName: String,

Answer

This is a pretty unfortunate error message, I must say, since Scala doesn't actually have a concept named "constant", so how are you supposed to make something a "constant" if you don't even know what it is?

Scala does, however, have a concept of "constant expression" (bold emphasis mine):

6.24 Constant Expressions

Constant expressions are expressions that the Scala compiler can evaluate to a constant. The definition of "constant expression" depends on the platform, but they include at least the expressions of the following forms:

  • A literal of a value class, such as an integer
  • A string literal
  • A class constructed with Predef.classOf
  • An element of an enumeration from the underlying platform
  • A literal array, of the form Array(c1, …, cn), where all of the ci's are themselves constant expressions
  • An identifier defined by a constant value definition.

and "constant value definition" (bold emphasis mine):

A constant value definition is of the form

final val x = e

where e is a constant expression. The final modifier must be present and no type annotation may be given.

So, as you can see, your expression is not a constant value expression, because the definition is not a constant value definition.

In order to turn it into a constant value definition, you need to

  • remove the type annotation : String
  • add the final modifier explicitly: even though members of a singleton object are implicitly final, constant value definitions require an explicit annotation

The result would look something like this:

object ProductAdded {
  final val PRODUCT_NAME  = "productName"
  final val PRODUCT_PRICE = "productPrice"
}

class ProductAdded @JsonCreator()(
  @JsonProperty(PRODUCT_NAME)  var productName:  String,
  @JsonProperty(PRODUCT_PRICE) var productPrice: String
) extends Event {
  @JsonProperty(PRODUCT_NAME)  def getProductName  = productName
  @JsonProperty(PRODUCT_PRICE) def getProductPrice = productPrice
}
Comments