scala - 如何识别没有底层java字段的scala构造函数参数 'fields'?

标签 scala reflection

我在 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 反射工作得很好,但这是有悖于这一点的。有任何想法吗?

最佳答案

为了避免错误如何过滤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)

关于scala - 如何识别没有底层java字段的scala构造函数参数 'fields'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17244180/

相关文章:

java - 在 Java 代码中使用 Scala 类型别名

scala - 有没有办法将默认大小写值作为参数传递

Go:再次将类型为 uuid.UUID (satori) 的 reflect.Value 转换回 uuid.UUID

java - 用最少的字符表示长

scala - 使用参数默认值键入删除

java - 在这种情况下,新的 JVM 实例或反射会有帮助吗

c# - 使用表达式树动态构建 EF4 查询,NotSupportedException

swift - 如何通过镜像更改变量的值?

java - 有哪些 java api 可以帮助使用反射进行注释处理?

scala - SBT 多项目找不到 logback 扩展