从scala调用java泛型函数

Jon*_*ore 3 generics scala

我是scala的新手,在java NIO库(来自scala 2.10.x)中调用"泛型"函数时遇到了问题.将代码简化为简单测试:

import java.net._
import java.nio.channels.{MembershipKey, DatagramChannel}

object Test {
  val channel = DatagramChannel.open(StandardProtocolFamily.INET)
    .setOption(StandardSocketOptions.SO_REUSEADDR, true)
    ...
}
Run Code Online (Sandbox Code Playgroud)

这导致:

Error:(40, 48) type mismatch;
 found   : java.net.SocketOption[Boolean]
 required: java.net.SocketOption[Any]
Note: Boolean <: Any, but Java-defined trait SocketOption is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
  channel.setOption(StandardSocketOptions.SO_REUSEADDR, true)
                                           ^
Run Code Online (Sandbox Code Playgroud)

我假设有一些方法可以解决这个问题,而无需在java中编写包装器.尝试过以各种方式重铸而没有成功.

问题:我该如何解决上述问题?

4e6*_*4e6 6

方法setOption是多态的

setOption[T](name: SocketOption[T], value: T): DatagramChannel
Run Code Online (Sandbox Code Playgroud)

所以打电话的时候

setOption(StandardSocketOptions.SO_REUSEADDR, true)
Run Code Online (Sandbox Code Playgroud)

scala看到那些类型的参数略有不同

StandardSocketOptions.SO_REUSEADDR: SocketOption[java.lang.Boolean]
true: scala.Boolean
Run Code Online (Sandbox Code Playgroud)

和编译器试图缩小T之间的最常见的类型java.lang.Boolean <: AnyRefscala.Boolean <: AnyValAny

要解决此问题,您需要为其提供显式类型 setOption

setOption[java.lang.Boolean](StandardSocketOptions.SO_REUSEADDR, true)
Run Code Online (Sandbox Code Playgroud)

或使用类型归属(然后T将正确推断)

setOption(StandardSocketOptions.SO_REUSEADDR, true: java.lang.Boolean)
Run Code Online (Sandbox Code Playgroud)