使用 Scala Option 中的空值实例化 POJO

Instanciating POJO with nulls values from Scala Option

使用 Scala 多年,但我仍然不知道与 Java 进行互操作的正确方法。 :(

老实说,这不是我每天都在做的事情,但有时别无选择(今天是 Firestore Java 库)。

我今天的问题是关于实例化可以具有空值的 POJO 的正确方法。 归根结底,我总是使用 def toJavaLong(l: Option[Long]): java.lang.Long = if (l.isEmpty) l.get else null 之类的东西,但可以肯定的是,还有更好更优雅的方法。

拜托,你能告诉我路径吗?我希望像 orNull 这样的东西开箱即用,但事实并非如此。

我正在使用 Scala 2.13,但您也可以随意展示 Scala 3 的替代方案。

在下一个示例中,我将解释我使用 orNullgetOrElse:

时遇到的错误

波乔:

public class ExamplePojo {
   public Long value;

   public ExamplePojo(Long value) {
      this.value = value;
   }
}

实例化 Pojo 的 Scala 对象:

object CreatePojo {
  def main(args: Array[String]): Unit = {
    val noneValue = Option.empty[Long]
    val oneValue = Some(1L)

    def toJavaLong(l: Option[Long]): java.lang.Long =
      if (l.isEmpty) l.get else null

    // Next line works fine.
    new ExamplePojo(toJavaLong(noneValue))

    // Next line works fine of course, but not helpful. :)
    new ExamplePojo(oneValue.get)

    // Next line throws a compilation error:
    // type arguments [Long] do not conform to method orNull's type parameter bounds [A1 >: Long]
    new ExamplePojo(noneValue.orNull)

    // Next line throws a compilation error:
    // type mismatch;
    //  found   : Any
    //  required: Long
    new ExamplePojo(noneValue.getOrElse(null))

    // This will throw a `java.util.NoSuchElementException`
    new ExamplePojo(noneValue.get)
  }
}

当然,这只是重现案例的例子。

在这种情况下,问题不在于 null,而是 scala.Longjava.lang.Long

不同这一事实

您可以做的是:

new ExamplePojo(l.map(Long.box).orNull)

可能不像您期望的那样简洁,但我倾向于使用以下内容:

option.getOrElse(null).asInstanceOf[java.lang.Long]

或者编写一个扩展方法 asJavaOrNull 来完成您 toJavaLong 目前所做的事情,但具有更好的开发人员体验。