首页 > 解决方案 > 在 Scala 中根据类名动态实例化一个类

问题描述

我有一组类,每个类都有一个名为Description.
我希望我的图书馆的最终用户能够指定他们感兴趣的类并能够阅读该描述。因此,我希望能够动态实例化每个指定的类并返回Description.

我知道我需要反思才能做到这一点,并且我已经看到很多 SO 问题建议Class.forName可以帮助我,但我无法让它发挥作用。

希望以下内容展示了我想要做的事情:

scala> abstract class Feature (start: Short, end: Short){val description: String}
defined class Feature

scala> class Feature1 (start: Short, end: Short) extends Feature(start, end){override val description = "this is feature 3"}
defined class Feature1

scala> class Feature2 (start: Short, end: Short) extends Feature(start, end){override val description = "this is feature 2"}
defined class Feature2

scala> class Feature3 (start: Short, end: Short) extends Feature(start, end){override val description = "this is feature 3"}
defined class Feature3

scala> val classesForWhichIWantToGetTheDescription = Set[String]("Feature1", "Feature2")
classesForWhichIWantToGetTheDescription: scala.collection.immutable.Set[String] = Set(Feature1, Feature2)

scala> val classesWithDescriptions = classesForWhichIWantToGetTheDescription.map(
     |     className => (className, s"I want the class description of ${className} to be displayed here")
     | )
classesWithDescriptions: scala.collection.immutable.Set[(String, String)] = Set((Feature1,I want the class description of Feature1 to be displayed here), (Feature2,I want the class description of Feature2 to be displayed here))

scala> classesWithDescriptions.foreach(
     |     c => println(c)
     | )
(Feature1,I want the class description of Feature1 to be displayed here)
(Feature2,I want the class description of Feature2 to be displayed here)

谁能帮我实现这一目标?

提前致谢

标签: scalareflection

解决方案


尝试

val classesWithDescriptions = classesForWhichIWantToGetTheDescription.map(
  className => {
    val clazz = Class.forName(className)
    val field = clazz.getDeclaredField("description")
    field.setAccessible(true)
    val constructor = clazz.getConstructor(classOf[Short], classOf[Short])
    val instance = constructor.newInstance(0: Short, 0: Short)
    val description = field.get(instance)
    (className, s"description of $className: $description")
  }
)

推荐阅读