7

私はscalaでリフレクションで遊んでいます。私が選んだ

class CloneSubject(val a :Int, b :String, private var c :Boolean)

typeOf[CloneSubject].membersサブジェクトとしてフィールドを検索するために繰り返し処理しますが ( sym.isTerm && (sym.asTerm.isVar || sym.asTerm.isVal))、FieldMirror を作成しようとすると ( )、次のcm mirrorField sym.asTerm例外が発生します。

Exception in thread "main" scala.ScalaReflectionException: Scala field b isn't represented as a Java field, 
neither it has a Java accessor method
note that private parameters of class constructors don't get mapped onto fields and/or accessors,
unless they are used outside of their declaring constructors.` 

これで、なぜこれが起こるのか完全に理解できましたが、例外をスローせずにこれを確認する方法が見つかりません。もちろん、Java リフレクションを使用しても問題なく動作しますが、それは的外れです。何か案は?

4

2 に答える 2

1

bエラーを回避するには、事前に除外することをお勧めします。

scala> val m = reflect.runtime.universe.runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror with ...

scala> val im = m.reflect(new CloneSubject(5, "hello", true))
im: reflect.runtime.universe.InstanceMirror = instance mirror for CloneSubject@2a95e173

scala> val fields = typeOf[CloneSubject].members collect { case m: MethodSymbol if m.isGetter => m.accessed }
fields: Iterable[reflect.runtime.universe.Symbol] = List(variable c, value a)

scala> fields map (s => im.reflectField(s.asTerm).get)
res45: Iterable[Any] = List(true, 5)

アクセス可能なすべてのフィールドには Getter があることがわかっているため、既存のすべての Getter によって表されるフィールドを取得するだけです。

val/var に Getter があるかどうかを確認するために使用する別のオプション:

scala> typeOf[CloneSubject].members.filter(s => s.isTerm && (s.asTerm.isVar || s.asTerm.isVal) && s.asTerm.getter != NoSymbol)
res50: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(variable c, value a)
于 2013-06-22T00:57:28.077 に答える
1

目に見えないインクで書くには、レモン汁を使用できます。

scala> typeOf[CloneSubject].members.collect { case s if s.name.decoded.endsWith(" ") => s }
res9: Iterable[reflect.runtime.universe.Symbol] = List(variable c, value a)

scala> cm reflect new CloneSubject(8, "foo", true)
res11: reflect.runtime.universe.InstanceMirror = instance mirror for CloneSubject@cdeca29

scala> res9 map (res11 reflectField _.asTerm) map (_.get)
res12: Iterable[Any] = List(true, 8)

神秘的な空間は次のとおりです。

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> nme.
CONSTRUCTOR           EMPTY                 EMPTY_PACKAGE_NAME    ERROR                 
LOCAL_SUFFIX_STRING   NameType              PACKAGE               ROOTPKG               
WILDCARD              asInstanceOf          isInstanceOf          toString              

scala> nme.LOCAL_SUFFIX_STRING
res0: String = " "
于 2013-06-22T06:58:32.493 に答える