在Scala中构造/构建JavaBean对象的最简洁方法是什么?

Hen*_*wan 4 java oop setter scala builder

假设Product是在我无法调整的Java库中,所以通过调用setter实例化它:

val product = new Product
product.setName("Cute Umbrella")
product.setSku("SXO-2")
product.setQuantity(5)
Run Code Online (Sandbox Code Playgroud)

我更愿意做这样的事情:

val product = new Product {
  _.setName("Cute Umbrella")
  _.setSku("SXO-2")
  _.setQuantity(5)
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是:

val product =
  new Product(name -> "Cute Umbrella", sku -> "SXO-2", quantity -> 5)
Run Code Online (Sandbox Code Playgroud)

Scala可以这样吗?

ret*_*nym 6

您可以导入setter,这样您就不需要限定调用:

val product = {
  val p = new Product
  import p._

  setName("Cute Umbrella")
  setSku("SXO-2")
  setQuantity(5)

  p
}
Run Code Online (Sandbox Code Playgroud)

如果Product不是最终的,您也可以匿名子类并在构造函数中调用setter:

val product = new Product {
  setName("Cute Umbrella")
  setSku("SXO-2")
  setQuantity(5)
}
Run Code Online (Sandbox Code Playgroud)

一旦尝试使用属性名称和值的Map进行实例化,就会在求助于反射时丢失静态类型检查.像Apache Commons BeanUtils这样的库可以提供帮助,如果你还想走这条道路的话.

另一种方法是传递一系列匿名函数来调用每个setter,并编写一个实用程序方法将它们应用于对象

def initializing[A](a: A)(fs: (A => Unit)*) = { fs.foreach(_(a)); a }

initializing(new Product)(
  _.setName("Cute Umbrella"),
  _.setSku("SXO-2"),
  _.setQuantity(5)
)
Run Code Online (Sandbox Code Playgroud)


Mik*_*x6r 6

您可以将Product对象创建为工厂,并在scala中调用它.像这样的东西:

object Product {
  def apply(name: String, sku: String, quantity: Int) = {
     val newProd = new Product()
     import newProd._
     setName(name)
     setSku(sku)
     setQuantity(quantity)
     newProd
}
Run Code Online (Sandbox Code Playgroud)

然后你可以完全按照自己的意愿使用它(没有新的).

   val product = Product(name = "Cute Umbrella", sku = "SXO-2", quantity = 5)
Run Code Online (Sandbox Code Playgroud)

(如果以上不编译,请道歉.在工作中无法访问Scala :(