【问题标题】:Convert scala future to java future将 Scala 未来转换为 Java 未来
【发布时间】:2019-06-09 18:40:33
【问题描述】:

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

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

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

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

问题是ask返回scala.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]))
                  ^

如何进行这种转换?

【问题讨论】:

    标签: java scala akka future scala-java-interop


    【解决方案1】:

    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>
    

    【讨论】:

    • 能否请您提供转换后的未来如何处理取消的信息?
    【解决方案2】:

    转换它们是不切实际的,因为 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。但我不会推荐它,因为它不稳定

    【讨论】:

      【解决方案3】:

      我认为没有一种简单的方法可以将 scala Future 转换为 java Future。一种可能的解决方案是通过 java future 包装 scala future,但您必须将新任务传递给线程池,请参阅 java 文档: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-29
        • 2016-02-06
        • 1970-01-01
        • 1970-01-01
        • 2020-11-19
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        相关资源
        最近更新 更多