使用scala方法返回java列表

时间:2015-11-17 20:23:03

标签: scala scala-java-interop

有人能帮助我吗?我试图将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);
}

recipelistHashMap。通过compoundRecipe检索recipelist.get("string")并投放到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!") 
}

而不是recipelist,我在这里使用recipes,一个不可变的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,aspects:AspectList,recipe: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!")

}

1 个答案:

答案 0 :(得分:1)

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

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