将 Scala 未来转换为 java 未来
Convert scala future to java future
我有一个生成的 java 接口包含一个方法:
public Future<?> getCustomersAsync(AsyncHandler<Customer> asyncHandler);
我想用Akka来实现。我写了以下内容:
override def getCustomerAsync(asyncHandler: AsyncHandler[Customer]): Future[_] = {
myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
}
问题是 ask
returns scala.concurrent.Future[Any]
并且方法必须 return java.util.concurrent.Future[?]
:
Error:(33, 17) type mismatch;
found : scala.concurrent.Future[Any]
required: java.util.concurrent.Future[?]
myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
^
我该如何进行这种转换?
我认为没有简单的方法可以将 scala Future 转换为 java Future。一种可能的解决方案是将 scala future 包装成 java future 但您必须将新任务传递给线程池,请参阅 java 文档:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
转换它们是不切实际的,因为 scala Future
不提供中断功能或任何其他取消机制。因此,没有直接的完全证明方法来通过中断或通过 Future 中的方法调用来取消未来。
因此,如果不需要取消,最简单的解决方案是:
def convert[T](x:Future[T]):java.util.concurrent.Future[T]={
new concurrent.Future[T] {
override def isCancelled: Boolean = throw new UnsupportedOperationException
override def get(): T = Await.result(x, Duration.Inf)
override def get(timeout: Long, unit: TimeUnit): T = Await.result(x, Duration.create(timeout, unit))
override def cancel(mayInterruptIfRunning: Boolean): Boolean = throw new UnsupportedOperationException
override def isDone: Boolean = x.isCompleted
}
}
但是,如果您仍然需要 cancel
,则残障修复将如图所示
here。但我不推荐它,因为它不稳定
从 Scala 2.13
开始,标准库包括 scala.jdk.FutureConverters
,它提供 Scala 到 Java Future
的转换(反之亦然):
import scala.jdk.FutureConverters._
// val scalaFuture: scala.concurrent.Future[Int] = Future.successful(42)
scalaFuture.asJava
// java.util.concurrent.CompletionStage[Int] = <function1>
注意 Java 用户,您宁愿使用 FutureConverters
明确的方式:
import scala.jdk.javaapi.FutureConverters;
// val scalaFuture: scala.concurrent.Future[Int] = Future.successful(42)
FutureConverters.asJava(scalaFuture);
// java.util.concurrent.CompletionStage[Int] = <function1>
我有一个生成的 java 接口包含一个方法:
public Future<?> getCustomersAsync(AsyncHandler<Customer> asyncHandler);
我想用Akka来实现。我写了以下内容:
override def getCustomerAsync(asyncHandler: AsyncHandler[Customer]): Future[_] = {
myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
}
问题是 ask
returns scala.concurrent.Future[Any]
并且方法必须 return java.util.concurrent.Future[?]
:
Error:(33, 17) type mismatch;
found : scala.concurrent.Future[Any]
required: java.util.concurrent.Future[?]
myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
^
我该如何进行这种转换?
我认为没有简单的方法可以将 scala Future 转换为 java Future。一种可能的解决方案是将 scala future 包装成 java future 但您必须将新任务传递给线程池,请参阅 java 文档: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
转换它们是不切实际的,因为 scala Future
不提供中断功能或任何其他取消机制。因此,没有直接的完全证明方法来通过中断或通过 Future 中的方法调用来取消未来。
因此,如果不需要取消,最简单的解决方案是:
def convert[T](x:Future[T]):java.util.concurrent.Future[T]={
new concurrent.Future[T] {
override def isCancelled: Boolean = throw new UnsupportedOperationException
override def get(): T = Await.result(x, Duration.Inf)
override def get(timeout: Long, unit: TimeUnit): T = Await.result(x, Duration.create(timeout, unit))
override def cancel(mayInterruptIfRunning: Boolean): Boolean = throw new UnsupportedOperationException
override def isDone: Boolean = x.isCompleted
}
}
但是,如果您仍然需要 cancel
,则残障修复将如图所示
here。但我不推荐它,因为它不稳定
从 Scala 2.13
开始,标准库包括 scala.jdk.FutureConverters
,它提供 Scala 到 Java Future
的转换(反之亦然):
import scala.jdk.FutureConverters._
// val scalaFuture: scala.concurrent.Future[Int] = Future.successful(42)
scalaFuture.asJava
// java.util.concurrent.CompletionStage[Int] = <function1>
注意 Java 用户,您宁愿使用 FutureConverters
明确的方式:
import scala.jdk.javaapi.FutureConverters;
// val scalaFuture: scala.concurrent.Future[Int] = Future.successful(42)
FutureConverters.asJava(scalaFuture);
// java.util.concurrent.CompletionStage[Int] = <function1>