【问题标题】:Returning a java List with a scala method使用 scala 方法返回 java List
【发布时间】:2015-11-17 20:23:03
【问题描述】:

有人可以帮助我吗?我正在尝试将 Java 方法移植到 Scala,但我得到了 ClassCastException

这是可用的 Java 版本:

private static void addCompoundRecipe(String tag, String tagAddon, AspectList creationAspects, int sizeX, int sizeY, int sizeZ, Object... recipe)
{
    List<Object> compoundRecipe = Arrays.asList(new Object[] {creationAspects, Integer.valueOf(sizeX), Integer.valueOf(sizeY), Integer.valueOf(sizeZ), Arrays.asList(recipe)});
    recipelist.put(tag+tagAddon, compoundRecipe);
}

recipelist 是一个HashMap。当通过recipelist.get("string") 检索compoundRecipe 并将其转换为List 时,一切正常。

麻烦的转换来了:

private def addCompoundRecipe(tag: String, tagAddon: String, sizeX: Int, sizeY: Int, sizeZ: Int, aspects: AspectList, recipe: AnyRef*) {
  val compoundRecipe = java.util.Arrays.asList(Array(sizeX, sizeY, sizeZ, aspects, java.util.Arrays.asList(recipe)))
  if(compoundRecipe.isInstanceOf[java.util.List[_]]) 
    recipes += (tag+tagAddon -> compoundRecipe) 
  else
    throw new IllegalArgumentException(s"$tag$tagAddon is not a valid recipe!") 
}

这里我使用recipes,而不是recipelist,这是一个不可变的HashMap。 当然,当我用recipes.apply("string") 调用它时,我必须使用.asInstanceOf[java.util.List[_]] 再次强制转换以使其符合方法的签名

问题是,我收到了ClassCastException

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to thaumcraft.api.aspects.AspectList

当然我可以写一个 Java 类来做这些事情,但这对我来说是一个挑战,我真的很想进入 Scala。

编辑: 我已经粘贴了第 387 行,它是 r.get(0),ResearchPage 是一个简单的类,它有一个带有 java.util.List 参数的构造函数,这就是我想要做的。没有必要对此进行更多的研究,因为它是一个 API,我无法更改它,而且当我用 Java 编写我的东西时它可以工作。但是,似乎我在转换时遇到问题...这是我一直在尝试的:`private def addCompoundRecipe(tag: String, tagAddon: String, sizeX: Int, sizeY: Int, sizeZ: Int, aspect: AspectList , 配方:ItemStack*) {

val compoundRecipe = (Seq(aspects, sizeX, sizeY, sizeZ, recipe.toSeq))
if(recipe != null) recipes += (tag+tagAddon -> compoundRecipe) else
  throw new IllegalArgumentException(s"$tag$tagAddon is not a valid recipe!")

}

这是我现在得到的例外: java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to java.util.List 当然在同一行 387 中。所以我猜问题出在隐式转换上?

编辑:这可行:

private def addCompoundRecipe(tag: String, tagAddon: String, sizeX: Int, sizeY: Int, sizeZ: Int, aspects: AspectList, recipe: AnyRef*) {

val compoundRecipe = Seq(aspects, sizeX, sizeY, sizeZ, recipe.asJava)
if(recipe != null) recipes += (tag+tagAddon -> compoundRecipe.asJava) else
  throw new IllegalArgumentException(s"$tag$tagAddon is not a valid recipe!")

}

【问题讨论】:

  • 您能否在提取配方并尝试投射时显示更多代码?
  • 异常消息意味着您有一个 Object[](对象数组,而不是列表!),您正尝试将其转换为 thaumcraft.api.aspects.AspectList
  • @Dr_Benway 请指定产生类转换异常的行以及recipes 哈希映射的完整类型(包括类型参数)。
  • 如果没有完整的 scala 代码,很难判断没有完整的代码......但让我们从这里开始:isInstanceOf 调用将始终评估为 true,因为这是 @ 的指定返回类型987654346@。另外,你最好使用这个:scala-lang.org/api/current/…
  • 是的,对于那个特定的问题,但可能不是导致实际问题的原因。您可能需要发布完整的 scala 代码以获得更好的建议。

标签: scala scala-java-interop


【解决方案1】:

我的猜测是val compoundRecipe = java.util.Arrays.asList(Array(sizeX, sizeY, sizeZ, aspects, java.util.Arrays.asList(recipe))) 行有问题,您希望在其中得到一个包含sizeXsizeYjava.util.List[Any]...但不幸的是,您得到的实际上是java.util.List[Array[Any]],其中内部Array 包含 sizeXsizeY... 如果您将它们传递给您的 java 方法调用,则不会检查类型。

我认为在 scala 代码中混合 java 类型和 scala 类型不是一个好主意(例如 val compoundRecipe = java.util.Arrays.asList ...if (compoundRecipe.isInstanceOf[java.util.List[_]))。似乎更好的做法是始终在代码中使用 scala 类型,并且仅在必要时进行转换(按照 @Alvaro 的建议使用 .asJava)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-21
    • 2017-12-29
    • 1970-01-01
    • 2017-07-31
    • 2023-03-06
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    相关资源
    最近更新 更多