There are several methods I need to write in Java, most of the system is in scala. Interop is not much of an issue except for one case.
I have a java method which takes a generic T in the call to a method, the generic being passed in is actually a scala case class. The challenge I am having is calling the overloaded apply method of the case class from within the java code. It cannot resolve the method apply. I have tried several variations of an extends definition for T but none seem to solve the problem.
Any suggestions? Here is a simplified version of the code so far:
Java (method in question)
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 case class (with overloaded apply method), one of many possible case 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")
)
}
}
There are two problems in your code:
Java generics are erased at runtime, so in order to do something like T.apply
, you'd need an instance of the T
, so your method would look like:
public <T> Option<T> getResult(String name, T t)
You need an upper bound where the apply
method would be defined to ensure that you can call the method on T
. However, scala declares this in the companion object, which is a separate class from the class it accompanies. And there's no super class for companion objects that describes which apply
methods they should implement.
The only thing I could think of is, if you known that the apply
method takes only 1 parameter:
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());
...
}
With this approach, you'd call the method like this:
getResult("name", Person$.MODULE$) //pass the companion object as a factory
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.