将 scala future 转换为 java future

2022-09-03 02:29:33

我有一个生成的java接口,其中包含一个方法:

public Future<?> getCustomersAsync(AsyncHandler<Customer> asyncHandler);

我想使用Akka实现它。我写了以下内容:

override def getCustomerAsync(asyncHandler: AsyncHandler[Customer]): Future[_] = {
  myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
}

问题是返回,并且该方法必须返回:askscala.concurrent.Future[Any]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]))
                  ^

如何进行此转换?


答案 1

首先,标准库包括 scala.jdk.FutureConverters,它提供了 Scala 到 Java 的转换(反之亦然):Scala 2.13Future

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>

答案 2

好吧,转换它们是不切实际的,因为scala不提供中断或任何其他取消机制的功能。因此,没有直接的完全证明的方法可以通过中断或以其他方式通过将来的方法调用来取消未来。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

在这里。但我不会推荐它,因为它摇摇欲坠