2016-10-05 8 views
3

リフレクションを使用して、パッケージオブジェクトに定義されたフィールドを取得する必要があります。パッケージオブジェクトのフィールドのFieldMirrorを取得する

package com.coryklein 

package object kittens { 
    val purr = "meow" 
} 

Mirrors documentationは言う:

Scalaはオブジェクトのみのインスタンスmethods--メソッドがオブジェクトインスタンスのインスタンスメソッドですしている、ModuleMirror.instance

によって得る寛大にもありますリフレクションを使用して定義されたクラスのメソッドxを呼び出す例C

scala> class C { def x = 2 } 
defined class C 

scala> val im = m.reflect(new C) 
im: reflect.runtime.universe.InstanceMirror = instance mirror for [email protected] 

scala> val methodX = typeOf[C].declaration(TermName("x")).asMethod 
methodX: reflect.runtime.universe.MethodSymbol = method x 

scala> val mm = im.reflectMethod(methodX) 
mm: reflect.runtime.universe.MethodMirror = method mirror for C.x: scala.Int (bound to [email protected]) 

scala> mm() 
res0: Any = 2 

ここから、パッケージオブジェクトに存在するフィールドを反映させるアプローチを適用することはあまり難しくありません。ただし、パッケージオブジェクトには、リフレクションからフィールドを取得するための対応するクラスがありません。

私は項記号入手することができました:

val ts: TermSymbol = mirror.staticPackage("com.coryklein.kittens").info.decls 
    .find(_.name.decodedName.toString == "purr").get.asTerm 

をしかし、この時点で、私がこのフィールドを反映するために、上からimと同等のインスタンス鏡を持っていません。

purr valは、Scalaのリフレクションによってパッケージオブジェクトkittensに定義されていますか?

答えて

2

ここで重要な部分はcom.coryklein.kittens.package$命名されてしまう実際のモジュールを、見つけることです:

scala> import scala.reflect.runtime.{ universe => ru } 

import scala.reflect.runtime.{universe=>ru} 

scala> val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader) 

runtimeMirror: reflect.runtime.universe.Mirror = JavaMirror with [email protected]7 of type class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [(memory)] and parent being [email protected]9b76 of type class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader with classpath [file:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/resources.jar,file:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/rt.jar,file:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/jsse.jar,file:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/jce.jar,file:/Library/Jav... 

scala> val moduleSymbol = runtimeMirror.staticModule("com.coryklein.kittens.package$") 

moduleSymbol: reflect.runtime.universe.ModuleSymbol = object package$ 

scala> val moduleMirror = runtimeMirror.reflectModule(moduleSymbol) 

moduleMirror: reflect.runtime.universe.ModuleMirror = module mirror for com.coryklein.kittens.package$ (bound to null) 

scala> val moduleInstance = moduleMirror.instance 

moduleInstance: Any = [email protected] 

scala> val instanceMirror = runtimeMirror.reflect(moduleInstance) 

instanceMirror: reflect.runtime.universe.InstanceMirror = instance mirror for [email protected] 

scala> val fieldSymbol = instanceMirror.symbol.info.member(ru.TermName("purr")).asTerm.accessed.asTerm 

fieldSymbol: reflect.runtime.universe.TermSymbol = value purr 

scala> val fieldMirror = instanceMirror.reflectField(fieldSymbol) 

fieldMirror: reflect.runtime.universe.FieldMirror = field mirror for private[this] val purr: java.lang.String (bound to [email protected]) 

scala> fieldMirror.get 

res0: Any = meow 

scala> 

私は私のtarget/scala-2.12/classesディレクトリにチャンスをうかがって、モジュールの名前を考え出した、とあちこちjavapを実行しています。

関連する問題