【问题标题】:Calling overloaded scala case apply from java using java generic使用java泛型从java调用重载的scala案例
【发布时间】:2015-05-22 15:53:52
【问题描述】:

我需要用 Java 编写几种方法,大部分系统都是在 scala 中编写的。除了一种情况外,互操作不是什么大问题。

我有一个 java 方法,它在对方法的调用中采用泛型 T,传入的泛型实际上是一个 scala 案例类。我面临的挑战是从 Java 代码中调用案例类的重载应用方法。它无法解决方法应用。我已经尝试了 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")
    )
  }
}

【问题讨论】:

  • 你需要一个Person 的实例并且你必须向上绑定类型参数。
  • T 应该是任何情况类或总是 Person (在这种情况下你不需要泛型)
  • @kocko 我尝试了public &lt;T extends Person&gt; Option&lt;T&gt; getResult(String name),但有问题的行上的错误是Required T but found Person。另外,我不想使用 Person,因为可以传入许多案例类类型。如果我为它们使用基类,我无法在 scala 中为基类伴随对象定义抽象应用方法。我错过了什么,你能提供示例代码吗?谢谢。
  • @Chirlo 可以有很多案例类类型,所以需要泛型。如果我删除泛型并只使用 Person 的类型化参数,它就可以正常工作。

标签: java scala generics interop


【解决方案1】:

你的代码有两个问题:

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

    public &lt;T&gt; Option&lt;T&gt; getResult(String name, T t)

  2. 您需要定义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 

【讨论】:

  • @Chiro 谢谢它的工作——只需要在你的代码中调整一行:public &lt;T&gt; Option&lt;T&gt; getResult(String name, Function1&lt;Item, T&gt; companion) 错误的大括号——在语言之间切换的问题:),还需要为 T 类定义一个基本抽象类使用假的 apply() 方法来保持 Java 的快乐。我真的很想摆脱伴随的应用方法,但一次设置一个。
猜你喜欢
  • 2011-11-13
  • 1970-01-01
  • 2021-02-16
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多