【问题标题】:Scala -- class declared fields and access modifiersScala——类声明字段和访问修饰符
【发布时间】:2011-10-09 01:04:22
【问题描述】:

我一直在尝试在 Scala 中使用 Manifest 等,我很难找到一种在通过 getDeclaredFields 方法访问时使用对象字段的方法...

这是一个例子:

class Woah(val x: String, val y: String)

val w = new Woah("w_x", "w_y")
classOf[Woah].getDeclaredFields foreach (field => println(field.get(w))

我尝试了许多变体,例如在 Woah 类中创建一个方法,该方法执行与第三行代码相同的操作,但将 field.get(w) 替换为 field.get(this),它显示同样的例外。抛出的异常是:

java.lang.IllegalAccessException: Class Fun$Woah$$anonfun$1 can not access a member of class Fun$Woah with modifiers "private final"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
    at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
    at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
    at java.lang.reflect.Field.get(Field.java:358)
    at Fun$Woah$$anonfun$1.apply(Fun.scala:17)
    at Fun$Woah$$anonfun$1.apply(Fun.scala:17)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34)
    at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:35)
    at Fun$Woah.<init>(Fun.scala:17)
    at Fun$.main(Fun.scala:20)
    at Fun.main(Fun.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:81)
    at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:86)
    at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:81)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:86)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:83)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

我已经尽可能多地进行了搜索,目前我没有找到任何新的想法。据我所知,Woah 类中的“x”和“y”被声明为私有 final,因为它们在构造函数之外使用。所以我也尝试了这个:

class Woah(val x: String, val y: String) {
  def printParams = classOf[Woah].getDeclaredFields foreach { field =>
    println(field.get(this))
  }
}

不幸的是,同样的异常被抛出。有没有办法让这两个 vals 公开?或者是否有可能通过其他途径实现相同的目标?我只是对访问类字段值的集合感兴趣。

提前感谢您的帮助!

【问题讨论】:

    标签: scala field


    【解决方案1】:
    class Woah(val x: String, val y: String) {
      def printParams = classOf[Woah].getDeclaredFields foreach { field =>
        field.setAccessible(true)
        println(field.get(this))
      }
    }
    

    【讨论】:

    • 我对 setAccessible 方法不是很熟悉,但是保留 access 的初始值并在 println 之后将其放回不是更干净吗?
    • @Nicolas:是的,这可能是个好主意。我只是在测试中真正使用过它,并没有打扰,但在生产代码中,您可能希望它恢复。
    【解决方案2】:

    Scala 中的所有 JVM 字段都是私有的。在 Scala 中只能通过 getter 访问它们,因此它们与无参数方法之间没有区别。

    【讨论】:

      猜你喜欢
      • 2015-12-02
      • 2011-10-15
      • 2017-02-19
      • 1970-01-01
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2016-10-20
      相关资源
      最近更新 更多