2017-03-08 67 views
0

我正在尋找一種方法來將一個斯卡拉單例對象作爲一個字符串(例如:package1.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() = {} 
    } 
} 

如何才能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,反映EN斯卡拉-META解決這將是有趣。