问题描述
在Scala中,动态实例化对象并使用反射调用方法的最佳方法是什么?
In Scala, what's the best way to dynamically instantiate an object and invoke a method using reflection?
我想做与以下Java代码等效的Scala:
I would like to do Scala-equivalent of the following Java code:
Class class = Class.forName("Foo");
Object foo = class.newInstance();
Method method = class.getMethod("hello", null);
method.invoke(foo, null);
在上面的代码中,类名和方法名都是动态传递的.上面的Java机制可能可以用于Foo
和hello()
,但是Scala类型与Java并不一一对应.例如,可以为单例对象隐式声明一个类. Scala方法还允许使用各种符号作为其名称.两者都通过名称修改解决.参见 Java和Scala之间的互操作.
In the above code, both the class name and the method name are passed in dynamically. The above Java mechanism could probably be used for Foo
and hello()
, but the Scala types don't match one-to-one with that of Java. For example, a class may be declared implicitly for a singleton object. Also Scala method allows all sorts of symbols to be its name. Both are resolved by name mangling. See Interop Between Java and Scala.
另一个问题似乎是通过解决重载和自动装箱来匹配参数,如来自Scala的反思-《天堂与地狱》 .
Another issue seems to be the matching of parameters by resolving overloads and autoboxing, described in Reflection from Scala - Heaven and Hell.
推荐答案
有一种更简单的方法来反射地调用方法,而不必诉诸Java反射方法:使用结构化键入.
There is an easier way to invoke method reflectively without resorting to calling Java reflection methods: use Structural Typing.
只需将对象引用转换为具有必要方法签名的结构类型",然后调用该方法:不需要反射(当然,Scala在下面进行反射,但我们不需要这样做).
Just cast the object reference to a Structural Type which has the necessary method signature then call the method: no reflection necessary (of course, Scala is doing reflection underneath but we don't need to do it).
class Foo {
def hello(name: String): String = "Hello there, %s".format(name)
}
object FooMain {
def main(args: Array[String]) {
val foo = Class.forName("Foo").newInstance.asInstanceOf[{ def hello(name: String): String }]
println(foo.hello("Walter")) // prints "Hello there, Walter"
}
}
这篇关于Scala:如何动态实例化对象并使用反射调用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!