在Scala中,如何将null传递给期望Long的Java方法?

Dav*_*vid 1 java null interop scala

我有一个接受Long值的Java方法:

(in Java)
public void setValue(Long value);
Run Code Online (Sandbox Code Playgroud)

我知道Scala null不会扩展任何值类型,包括Long.因此,当我尝试将null传递给它时,我得到一个编译错误:

(in Scala)
javaThing.setValue(null)

==> type mismatch; found  : Any required: java.lang.Long
Run Code Online (Sandbox Code Playgroud)

编辑:aargh!忽略上面的代码片段.我过度简化了问题,并陷入了麻烦.事实上,问题来自我使用Option [Long],如下:

javaThing.setValue(calcValue.getOrElse(null))
Run Code Online (Sandbox Code Playgroud)

我认为,问题是getOrElse在给定null参数时求值为Any类型.

救命!

Kri*_*ala 10

使用显式强制转换asInstanceOf将起作用:

scala> val l:java.lang.Long = Some(2L).getOrElse(null).asInstanceOf[java.lang.Long]
l: java.lang.Long = 2

scala> val n:java.lang.Long = None.getOrElse(null).asInstanceOf[java.lang.Long]    
n: java.lang.Long = null
Run Code Online (Sandbox Code Playgroud)

所以,这样的事情应该有效:

javaThing.setValue(calcValue.getOrElse(null).asInstanceOf[java.lang.Long])
Run Code Online (Sandbox Code Playgroud)

它颠覆了类型系统,但首先使用null它.


小智 7

甚至更短:

null.asInstanceOf[Long]
Run Code Online (Sandbox Code Playgroud)


Dan*_*ral 5

我不能在这里重现.

JavaTst.java:

public class JavaTst {
    public void setValue(Long value) {}
}
Run Code Online (Sandbox Code Playgroud)

REPL:

scala> new JavaTst
res0: JavaTst = JavaTst@4e229e

scala> res0.setValue(null)

scala>
Run Code Online (Sandbox Code Playgroud)

编辑

啊哈!在这种情况下,这个复杂的代码将起作用:

res0.setValue(calcValue.map(new java.lang.Long(_)).getOrElse(null))
Run Code Online (Sandbox Code Playgroud)

我建议将java.lang.Long导入jlLong,以使其更短.

  • @David Scala的`Long`是一个`AnyVal`,因此没有'null`作为可能的值.所以我将它映射到`java.lang.Long`,它确实如此.一旦完成,Scala就可以推断出`null`的类型`java.lang.Long`,它不能用于`Long`. (2认同)