我需要用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")
)
}
}
答案 0 :(得分:2)
您的代码中存在两个问题:
Java泛型在运行时被删除,因此为了执行T.apply
之类的操作,您需要T
的实例,因此您的方法将如下所示:
public <T> Option<T> getResult(String name, T t)
您需要一个上限,其中将定义apply
方法,以确保您可以在T
上调用该方法。但是,scala在伴随对象中声明了这一点,该对象与它所伴随的类是一个单独的类。并且没有用于描述应该实现哪些apply
方法的伴随对象的超类。
我唯一能想到的是,如果你知道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