【问题标题】:Integrating scala with java将scala与java集成
【发布时间】:2013-07-28 22:43:25
【问题描述】:

我是 Scala 新手。我需要帮助来解决这个问题。
我已经构建了一个project which is written in Scala,并且正在尝试将它与 Java 项目集成。我在eclipse的Java项目中依赖了build scala jar。 但是,当我在 Scala jar 中调用一个方法时,我会在运行应用程序时得到 ClassCastException

以下是我得到的异常

线程“主”java.lang.ClassCastException 中的异常:com.rockymadden.stringmetric.phonetic.MetaphoneAlgorithm 无法转换为 com.rockymadden.stringmetric.StringFilter 在 com.rockymadden.stringmetric.phonetic.MetaphoneAlgorithm.compute(MetaphoneAlgorithm.scala:10) 在 org.gobe.search.dictionary.test.PhoneticTest.main(PhoneticTest.java:16)

我能做些什么来解决这个问题?

public static void main(String[] args) {
    MetaphoneMetric metric = new MetaphoneMetric();
    DummyImplicit di = new DummyImplicit();
    MetaphoneAlgorithm algo = new MetaphoneAlgorithm();
    char[] rr = {'h', 'e', 'l', 'l', 'o'};
    System.out.println(algo.compute(rr, di));
}

在上面的代码“MetaphoneMetric”中,“DummyImplicit”是我生成的 Scala Jar 的一部分。
Metaphone算法的逻辑可以在http://pastebin.com/d7CXjDtx找到

【问题讨论】:

  • 我能做些什么来解决这个问题?
  • 向我们展示MetaphoneAlgorithm.compute 方法的逻辑(尤其是第10 行)。看来你在那里执行了不正确的演员表。
  • 请在pastebin链接pastebin.com/Dgkb7rQz找到MetaphoneAlgorithm.compute()的逻辑
  • 顺便说一句,使用来自 java 的全功能 scala 类与反之亦然不同。同样在粘贴的代码中没有类MetaphoneAlgorithm,它是一个object
  • 我的错。我粘贴了错误的代码。这是正确代码pastebin.com/d7CXjDtx 的链接。我可以做些什么来解决这个问题?

标签: java scala implicits


【解决方案1】:

看代码,你的MetaphoneAlgorithm定义为:

class MetaphoneAlgorithm extends StringAlgorithm[...] { this: StringFilter =>
 ...
}

重要的是this: StringFilter =>。由于StringAlgorithm 尚未实现StringFilter,因此需要混合这种自我类型来创建MetaphoneAlgorithm

在 scala 中你会这样做:

val algo = new MetaphoneAlgorithm with StringFilter

编辑:正如@a​​im 回答的那样,这正是MetaphoneAlgorithm.apply() 返回的内容。这可能就是你想要的。

或者你会创建一个新类:

class MyAlgo extends MetaphoneAlgorithm with StringFilter

// and then
val algo = new MyAlgo

如果您希望能够在 java 端创建 MetaphoneAlgorithm with StringFilter

看你的StringFilter trait,应该是java端的接口。

编辑:可悲的是,StringFilter 将变成一个抽象类。提供与 java 的兼容性的方法是使 StringFilter 完全抽象:

trait StringFilter extends Filter[String] with StringFilterable {
  override def filter(charArray: Array[Char]): Array[Char]
}

以及Filter trait,然后将MetaphoneAlgorithm.apply() 定义为返回:

def apply(): MetaphoneAlgorithm = new MetaphoneAlgorithm with StringFilter
  with DefaultStringFilter

DefaultStringFilter 是您默认的StringFilter 实现(当前位于StringFilter 中的那个,也实现了Filter 中定义的方法)。

随着这一变化,这在 java 端成为可能:

public class MyAlgo extends MetaphoneAlgorithm implements StringFilter {
  /* implement StringFilter here */
}

然后在你的 main 方法中实例化那个。

这有点乱,但允许您在 java 端定义自定义 StringFilter 实现。


错误消息本身来自将(未写入的)this 转换为 StringFilter,因此我可以理解为什么该错误令人惊讶。

附带说明一下,有趣的是,它允许您直接实例化 MetaphoneAlgorithm 类,因为它根本不可能工作。我不确定这是否可以避免,但这是另一个有趣的 scala/java 兼容性问题。

【讨论】:

  • 我很想看看最后一个建议是否有效。我同意 StringFilter 将编译为标准接口,但我不知道自键入是否假设不仅仅是转换 this 实例。
  • 我对@9​​87654350@ 的了解还不够深入。它有一个实现,并且(更糟糕的是)它继承自一个具有实现的特征(Filter[A])。所以这不可能,但可以使它成为可能,请参阅编辑。
  • 如果我使用 Scala 库而不是 Java 库,会不会影响性能?我所说的性能影响是指运行时空间和时间复杂度?
  • @bourne:如果您的意思是“使用 Scala 中的 Scala 库与使用 Java 中的任何区别”,答案是否定的。这就是在通用平台(JVM)上运行的全部意义所在。如果您的意思是“使用这个 Scala 库与另一个 Java 库”,那么我只能说“它取决于”。
【解决方案2】:

请检查:

Predef.DummyImplicit di = new Predef.DummyImplicit();
MetaphoneAlgorithm algo = MetaphoneAlgorithm.apply();
char[] rr = {'h', 'e', 'l', 'l', 'o'};
System.out.println(Arrays.toString(algo.compute(rr, di).get()));

【讨论】:

  • 这行得通。万分感谢。您能否解释一下为什么上面的代码有效以及我做错了什么?
  • 我们只是创建了默认实现MetaphoneAlgorithm with StringFilter,如上所述。请参阅this
【解决方案3】:

您已经使用自类型注释定义了MetaphoneAlgorithm

class MetaphoneAlgorithm { this: StringFilter =>

这意味着该类不能使用,除非它混合了 StringFilter 特征(例如 new MetaphoneAlgorithm() with MyCoolStringFilter)。

由于您没有在示例中执行此操作,而您只是在构造一个普通的MetaphoneAlgorithm,因此代码无效。 Scalac 会让它编译,但 Java 编译器不理解 Scala 的注解,这些注解告诉它为什么这不起作用 - 所以你会在运行时得到错误。

事实上,我认为在纯 Java 代码中根本不可能做到这一点,因为您无法创建一个混入 trait* 的匿名类。如果你打算在 Java 中使用 Scala 类,那么考虑你希望 Java 用户调用什么接口是有意义的,然后确保你不要用它做任何太 Scala-y 的事情。

*好吧,如果你真的有动力,我想你可能可以,但你必须看看 Scala 如何在字节码级别编译 mixin,然后尝试模仿它。它会非常脆弱,而且不值得。

【讨论】:

    猜你喜欢
    • 2013-04-21
    • 2017-05-16
    • 2011-08-30
    • 2016-08-26
    • 2011-10-21
    • 1970-01-01
    • 2014-05-07
    • 2018-09-18
    • 1970-01-01
    相关资源
    最近更新 更多