2017-03-08 1 views
0

文字列(例えば:package1.Main)として与えられたScalaシングルトンオブジェクトを、実際のMainインスタンスに変換する方法を探しています。問題のScalaが文字列をシングルトンオブジェクトに反映する

例:

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() = {} 
    } 
} 

がどのようにmagicallyConvert1とmagicallyConvert2機能を実装することができますか?通常のクラスのために

答えて

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の-メタエンScalaの-反映して解決策を見るのは興味深いだろう。

関連する問題