0

文字列として指定された Scala シングルトン オブジェクト (package1.Main など) を Main の実際のインスタンスに変換して、メソッドを呼び出せるようにする方法を探しています。

問題の例:

package x {
  object Main extends App {
    val objectPath: String = io.StdIn.readLine("Give an object: ") // user enters: x.B

    // how to convert the objectPath (String) to a variable that references singleton B?
    val b1: A = magicallyConvert1(objectPath)
    b1.hi()

    val b2: B.type = magicallyConvert2(objectPath)
    b2.extra()
  }

  trait A {
    def hi() = {}
  }

  object B extends A {
    def extra() = {}
  }
}

magiclyConvert1 および magiclyConvert2 関数はどのように実装できますか?

4

2 に答える 2

1

通常のクラスの場合、これは次のようなものを使用して実行できます。

val b: A = Class.forName("x.B").newInstance().asInstanceOf[A]

しかし、Java リフレクションを使用して、シングルトンの解決策を見つけました。

Java では、次の名前でシングルトンにアクセスできます: package.SingletonName$.MODULE$ したがって、静的フィールドである "$.MODULE$" を追加する必要があります。したがって、標準の Java リフレクションを使用して取得できます。

したがって、解決策は次のとおりです。

def magicallyConvert1(objectPath: String) = {
  val clz = Class.forName(objectPath + "$")
  val field = clz.getField("MODULE$")
  val b: A = field.get(null).asInstanceOf[A]
  b
}

def magicallyConvert2(objectPath: String) = {
  val clz = Class.forName(objectPath + "$")
  val field = clz.getField("MODULE$")
  val b: B.type = field.get(null).asInstanceOf[B.type]
  b
}

しかし、Scala-Reflect と Scala-Meta を使用した解決策を見ることは興味深いでしょう。

于 2017-03-08T16:45:20.707 に答える