java.lang.NoSuchMethodException: scala.collection.immutable.$冒号$冒号
java.lang.NoSuchMethodException: scala.collection.immutable.$colon$colon
我正在尝试使用变量作为字符串类型动态调用函数,即变量将包含函数名称作为字符串。所以,我需要使用该变量调用一个函数。
所以,我正在使用 Scala 反射。如果函数接受数据类型为 Sting,它可以工作,但它会抛出错误 List[Map[String, Double]]
下面我用link引用了一个代码
Is there any Scala feature that allows you to call a method whose name is stored in a string?
以下是我正在尝试测试的测试程序
package test
import scala.collection.immutable.Map
class DynamicaVariable {
def cat(s1: List[Map[String, Double]]) = {
println(s1)
}
}
object DynamicaVariable{
def main(args: Array[String]): Unit = {
val obj = new DynamicaVariable
val data = List(
Map("a" -> 1.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0), Map("a" -> 1.0, "b" -> 2678.0, "c" -> 40.0, "d" -> 2.0), Map("a" -> 4.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0), Map("a" -> 1.0, "b" -> 2678.0, "c" -> 90.0, "d" -> 17.0)
)
val functionName = "cat"
val method = obj.getClass.getMethod(functionName,data.getClass)
method.invoke(obj,data)
}
}
我的 scala 版本是 2.11.6,我使用的是 IntelliJ。我也检查了 SDK 版本。并取消选中 scala
下的 "Run worksheet in the compile process"
但还是没有运气!任何想法都会有所帮助。谢谢!
如此处所述Runtime Classes in Java vs. Runtime Types in Scala
using Java reflection on Scala classes might return surprising or incorrect results
看来你的情况,因为data是scala.collection.immutable.List类型,你需要使用Scala反射来获取运行时 data val 的类型。这是一个例子
import scala.reflect.ClassTag
import scala.reflect.classTag
class DynamicaVariable {
def cat(s1: List[Map[String, Double]]) = {
println(s1)
}
}
object DynamicaVariable{
def main(args: Array[String]): Unit = {
val obj = new DynamicaVariable
val data = List(Map("a" -> 1.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0)
, Map("a" -> 1.0, "b" -> 2678.0, "c" -> 40.0, "d" -> 2.0)
, Map("a" -> 4.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0)
, Map("a" -> 1.0, "b" -> 2678.0, "c" -> 90.0, "d" -> 17.0))
val functionName = "cat"
val method = obj.getClass.getMethod(functionName, getClassOf(data).runtimeClass)
method.invoke(obj,data)
}
def getClassOf[T: ClassTag](obj: T) = classTag[T]
}
我在下面给出了一个可行的解决方案,该解决方案采用 scala 反射 与@ValentinCarnu 的 java/scala 混合。
我不是反射大师,所以我不知道下面是否符合惯用语。
import scala.collection.immutable.Map
import scala.reflect.runtime.{universe => ru}
class DynamicaVariable {
def cat(s1: List[Map[String, Double]]) = {
println(s1)
}
}
object DynamicaVariable {
def main(args: Array[String]): Unit = {
val obj = new DynamicaVariable
val data = List(
Map("a" -> 1.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0),
Map("a" -> 1.0, "b" -> 2678.0, "c" -> 40.0, "d" -> 2.0),
Map("a" -> 4.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0),
Map("a" -> 1.0, "b" -> 2678.0, "c" -> 90.0, "d" -> 17.0)
)
val functionName = "cat"
val mirror = ru.runtimeMirror(getClass.getClassLoader)
val instanceMirror: ru.InstanceMirror = mirror.reflect(obj)
val classSymbol = mirror.classSymbol(obj.getClass)
val termName: ru.MethodSymbol = classSymbol.info.decl(ru.TermName(functionName)).asMethod
val methodMirror: ru.MethodMirror = instanceMirror.reflectMethod(termName)
methodMirror.apply(data)
}
}
我正在尝试使用变量作为字符串类型动态调用函数,即变量将包含函数名称作为字符串。所以,我需要使用该变量调用一个函数。
所以,我正在使用 Scala 反射。如果函数接受数据类型为 Sting,它可以工作,但它会抛出错误 List[Map[String, Double]]
下面我用link引用了一个代码
Is there any Scala feature that allows you to call a method whose name is stored in a string?
以下是我正在尝试测试的测试程序
package test
import scala.collection.immutable.Map
class DynamicaVariable {
def cat(s1: List[Map[String, Double]]) = {
println(s1)
}
}
object DynamicaVariable{
def main(args: Array[String]): Unit = {
val obj = new DynamicaVariable
val data = List(
Map("a" -> 1.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0), Map("a" -> 1.0, "b" -> 2678.0, "c" -> 40.0, "d" -> 2.0), Map("a" -> 4.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0), Map("a" -> 1.0, "b" -> 2678.0, "c" -> 90.0, "d" -> 17.0)
)
val functionName = "cat"
val method = obj.getClass.getMethod(functionName,data.getClass)
method.invoke(obj,data)
}
}
我的 scala 版本是 2.11.6,我使用的是 IntelliJ。我也检查了 SDK 版本。并取消选中 scala
下的 "Run worksheet in the compile process"但还是没有运气!任何想法都会有所帮助。谢谢!
如此处所述Runtime Classes in Java vs. Runtime Types in Scala
using Java reflection on Scala classes might return surprising or incorrect results
看来你的情况,因为data是scala.collection.immutable.List类型,你需要使用Scala反射来获取运行时 data val 的类型。这是一个例子
import scala.reflect.ClassTag
import scala.reflect.classTag
class DynamicaVariable {
def cat(s1: List[Map[String, Double]]) = {
println(s1)
}
}
object DynamicaVariable{
def main(args: Array[String]): Unit = {
val obj = new DynamicaVariable
val data = List(Map("a" -> 1.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0)
, Map("a" -> 1.0, "b" -> 2678.0, "c" -> 40.0, "d" -> 2.0)
, Map("a" -> 4.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0)
, Map("a" -> 1.0, "b" -> 2678.0, "c" -> 90.0, "d" -> 17.0))
val functionName = "cat"
val method = obj.getClass.getMethod(functionName, getClassOf(data).runtimeClass)
method.invoke(obj,data)
}
def getClassOf[T: ClassTag](obj: T) = classTag[T]
}
我在下面给出了一个可行的解决方案,该解决方案采用 scala 反射 与@ValentinCarnu 的 java/scala 混合。
我不是反射大师,所以我不知道下面是否符合惯用语。
import scala.collection.immutable.Map
import scala.reflect.runtime.{universe => ru}
class DynamicaVariable {
def cat(s1: List[Map[String, Double]]) = {
println(s1)
}
}
object DynamicaVariable {
def main(args: Array[String]): Unit = {
val obj = new DynamicaVariable
val data = List(
Map("a" -> 1.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0),
Map("a" -> 1.0, "b" -> 2678.0, "c" -> 40.0, "d" -> 2.0),
Map("a" -> 4.0, "b" -> 267.0, "c" -> 26.0, "d" -> 2.0),
Map("a" -> 1.0, "b" -> 2678.0, "c" -> 90.0, "d" -> 17.0)
)
val functionName = "cat"
val mirror = ru.runtimeMirror(getClass.getClassLoader)
val instanceMirror: ru.InstanceMirror = mirror.reflect(obj)
val classSymbol = mirror.classSymbol(obj.getClass)
val termName: ru.MethodSymbol = classSymbol.info.decl(ru.TermName(functionName)).asMethod
val methodMirror: ru.MethodMirror = instanceMirror.reflectMethod(termName)
methodMirror.apply(data)
}
}