Scala反射生成一个伴生对象并调用apply方法
问题就在这里Scala反射生成一个伴生对象并调用apply方法,scala,reflection,companion-object,scala-reflect,Scala,Reflection,Companion Object,Scala Reflect,问题就在这里 trait TestTrait[T, R] extends (T => R) // Class implementing TestTrait. This is one class, there are a number of class implementing TestTrait class TestClass(val input: Map[String, String])extends ConfigurableDomainExtractor[String, Strin
trait TestTrait[T, R] extends (T => R)
// Class implementing TestTrait. This is one class, there are a number of class implementing TestTrait
class TestClass(val input: Map[String, String])extends ConfigurableDomainExtractor[String, String] {
override def apply(value: String): String = ???
}
// Companion Object
object TestClass {
def apply(properties: Map[String, String]): TestClass = TestClass(properties)
}
我想做的是在util类中定义一个方法
class CreateInstance {
def getInstance(fullyQualifiedClassName: String, properties: Map[String, String]): TestTrait = ???
// fullyQualifiedClassName is the name of the class that needs to be instantiated using its companion object. It can be TestClass or any class implementing TestTrait
// properties is the map that needs to be pass to the apply method of the companion object.
}
它将在传递类名时,通过首先获取一个伴随对象,然后调用传递映射的伴随对象上的apply来生成类实例,从而生成同一类的对象
我知道我们在scala有一些反映,我尝试了一些事情,但都没有用。以下是我尝试过的几件事
import scala.reflect.runtime.universe
def getInstance(fullyQualifiedClassName: String, properties: Map[String, String]): TestTrait = {
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = runtimeMirror.staticModule(fullyQualifiedClassName)
val obj = runtimeMirror.reflectModule(module)
obj.instance
.asInstanceOf[TestTrait[String, String]]
.apply(properties)
.asInstanceOf[TestTrait[String, String]]
}
有人能帮我完成def getInstance
方法吗 试试Scala反射
import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
def getInstance(fullyQualifiedClassName: String, properties: Map[String, String]): TestTrait[String, String] = {
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val objSymbol = runtimeMirror.staticModule(fullyQualifiedClassName)
val objMirror = runtimeMirror.reflectModule(objSymbol)
val obj = objMirror.instance
val objTyp = objSymbol.typeSignature
val methodSymbol = objTyp.decl(TermName("apply")).asMethod
val instanceMirror = runtimeMirror.reflect(obj)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(properties).asInstanceOf[TestTrait[String, String]]
}
getInstance("pckg.App.TestClass", Map("a" -> "b"))
def getInstance(fullyQualifiedClassName: String, properties: Map[String, String]): TestTrait[String, String] = {
val clazz = Class.forName(fullyQualifiedClassName)
val moduleField = clazz.getDeclaredField("MODULE$")
val obj = moduleField.get(null) // field MODULE$ is static
val applyMethod = clazz.getDeclaredMethod("apply", classOf[Map[_, _]])
applyMethod.invoke(obj, properties).asInstanceOf[TestTrait[String, String]]
}
getInstance("pckg.App$TestClass$", Map("a" -> "b"))
或Java反射
import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
def getInstance(fullyQualifiedClassName: String, properties: Map[String, String]): TestTrait[String, String] = {
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val objSymbol = runtimeMirror.staticModule(fullyQualifiedClassName)
val objMirror = runtimeMirror.reflectModule(objSymbol)
val obj = objMirror.instance
val objTyp = objSymbol.typeSignature
val methodSymbol = objTyp.decl(TermName("apply")).asMethod
val instanceMirror = runtimeMirror.reflect(obj)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(properties).asInstanceOf[TestTrait[String, String]]
}
getInstance("pckg.App.TestClass", Map("a" -> "b"))
def getInstance(fullyQualifiedClassName: String, properties: Map[String, String]): TestTrait[String, String] = {
val clazz = Class.forName(fullyQualifiedClassName)
val moduleField = clazz.getDeclaredField("MODULE$")
val obj = moduleField.get(null) // field MODULE$ is static
val applyMethod = clazz.getDeclaredMethod("apply", classOf[Map[_, _]])
applyMethod.invoke(obj, properties).asInstanceOf[TestTrait[String, String]]
}
getInstance("pckg.App$TestClass$", Map("a" -> "b"))
在这里,仅仅使用Java反射就足够了吗。。。?这要容易得多。@SethTisue如何使用Java反射API?