使用 java 泛型从 java 调用重载的 scala case apply

Calling overloaded scala case apply from java using java generic

有几个方法我需要写在Java,大部分系统在scala中。除了一个案例,Interop 不是什么大问题。

我有一个 java 方法,它在方法调用中采用泛型 T,传入的泛型实际上是一个 Scala 案例 class。我面临的挑战是从 java 代码中调用案例 class 的重载应用方法。它无法解决应用方法。我已经尝试了 T 的扩展定义的几种变体,但 none 似乎可以解决问题。

有什么建议吗?到目前为止,这是代码的简化版本:

Java(有问题的方法)

public <T> Option<T> getResult(String name) {
    Iterator<Item> items = repo.results(name).iterator();

    if (items.hasNext()) {
        T model = T.apply(items.next());  // ?? how to call overloaded case class apply method
        return new Some<>(model);
    }

    return scala.Option$.MODULE$.apply(null);
}

Scala 案例 class(具有重载的 apply 方法),许多可能的案例之一 classes.

case class Person (id: Int, name: String)

object Person {
  def apply(item: Item) = toObject(item)

  def toObject(item: Item): Person = {
    Person(
      item.getProperty[Int]("id"),
      item.getProperty("name")
    )
  }
}

你的代码有两个问题:

  1. Java 泛型在运行时被删除,所以为了做类似 T.apply 的事情,你需要一个 T 的实例,所以你的方法看起来像:

    public <T> Option<T> getResult(String name, T t)

  2. 您需要定义 apply 方法的上限,以确保您可以在 T 上调用该方法。但是,scala 在伴随对象中声明了它,它是一个独立于它伴随的 class 的 class。并且没有超级 class 用于描述它们应该实现哪些 apply 方法的伴随对象。

我唯一能想到的是,如果你知道 apply 方法只需要 1 个参数:

public <T> Option<T> getResult(String name, Function1<Item, T> companion){ // this is extended by companion objects of case class that take only 1 parameter
 ... 
  T model = companion.apply(items.next());
 ...
}

使用这种方法,您可以这样调用方法:

 getResult("name", Person$.MODULE$)  //pass the companion object as a factory