使用 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 的替代方案。
在下一个示例中,我将解释我使用 orNull
和 getOrElse
:
时遇到的错误
波乔:
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.Long
与 java.lang.Long
不同这一事实
您可以做的是:
new ExamplePojo(l.map(Long.box).orNull)
可能不像您期望的那样简洁,但我倾向于使用以下内容:
option.getOrElse(null).asInstanceOf[java.lang.Long]
或者编写一个扩展方法 asJavaOrNull
来完成您 toJavaLong
目前所做的事情,但具有更好的开发人员体验。
使用 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 的替代方案。
在下一个示例中,我将解释我使用 orNull
和 getOrElse
:
波乔:
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.Long
与 java.lang.Long
您可以做的是:
new ExamplePojo(l.map(Long.box).orNull)
可能不像您期望的那样简洁,但我倾向于使用以下内容:
option.getOrElse(null).asInstanceOf[java.lang.Long]
或者编写一个扩展方法 asJavaOrNull
来完成您 toJavaLong
目前所做的事情,但具有更好的开发人员体验。