调用重载的scala案例适用于java使用java泛型

时间:2015-05-21 12:58:27

标签: java scala generics interop

我需要用Java编写几种方法,大部分系统都在scala中。除了一个案例之外,Interop并不是一个问题。

我有一个java方法,它在调用方法时采用泛型T,传入的泛型实际上是一个scala案例类。我遇到的挑战是从java代码中调用case类的重载apply方法。它无法解决方法申请。我已经尝试了T的扩展定义的几种变体,但似乎都没有解决问题。

有什么建议吗?以下是目前代码的简化版本:

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案例类(带有重载的apply方法),是许多可能的案例类之一。

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 个答案:

答案 0 :(得分:2)

您的代码中存在两个问题:

  1. Java泛型在运行时被删除,因此为了执行T.apply之类的操作,您需要T的实例,因此您的方法将如下所示:

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

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

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

    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