在Scala/Java中获取实例的公共字段(以及它们各自的值)



PHP引入了一个方法,该方法允许您挑选一个实例的所有公共值。在Scala中有什么办法做到这一点吗?即获取实例化类(不是对象)的所有公共字段的所有值。

假设我有这个类

class TestElement( datatype: Datatype, var subject: String, var day: Int, var time: Int )
  extends DataElement( datatype: Datatype ) {    
   def to( group: Group ) = group.add( this );
}
var element = new TestElement( datatype, "subject", 1, 1 );

我需要从问题中的方法中获得一个Map或两个值的集合。

var element.method                                       // the function I need
ret: ( ("subject", "subject"), ("day", 1), ("time", 1) ) // its output

是睡觉的时间了,所以我没有时间给出完整的答案,但是看看element.getClass.getFields(或getDeclaredFields私有字段)的结果-您可以在Field对象上调用getValue(element)来获取它们的值。


现在醒了,仍然没有更好的答案,所以:

首先,请注意,在Java术语中,您的类没有公共字段subject,它只有私有字段subject和访问器方法subject()和subject_$eq(String)。

您可以像上面描述的那样遍历私有字段对象,从对中填充一个Map:

def getFields(o: Any): Map[String, Any] = {
  val fieldsAsPairs = for (field <- o.getClass.getDeclaredFields) yield {
    field.setAccessible(true)
    (field.getName, field.get(o)) 
  }
  Map(fieldsAsPairs :_*)
}

现在您可以在TestElement上定义这个方法(用this替换o),或者更一般地定义一个转换,这样您就可以在任何引用

上调用getFields
implicit def any2FieldValues[A](o: A) = new AnyRef {
  def fieldValues = getFields(o)
}

所以

element.fieldValues 

根据Philippe的回答,您可以对case类执行此操作。

更广泛地说,同样的技术适用于 Product的任何子类。和case类一样,Tuples是另一个明显的例子,但该列表远不止于此。

看一下"已知子类",在这里:http://www.scala-lang.org/api/current/scala/Product.html

对于case类,你可以做一些类似的事情:

case class SomeEntity(name : String, value : Int, misc : Boolean)
val s = SomeEntity("Tom", 42, false)
println(s.productIterator.map(_.toString).mkString(", ")) // "Tom, 42, false"

…如您所料,productIterator迭代Any类型的元素。此方法仅为case类自动生成,您将不检索字段的名称。对于更多的内容,您将需要使用反射,为此,您可能希望等待2.10版本发布。

对于那些试图通过使@duncan的方法类型更强来改进这一点的人:

不返回值类型为Any的Map[String, Any],您可以这样做:

def propertiesAsPairs() = {
    val fields = (this.getClass.getDeclaredFields())
    for ( field <- fields ) yield {
        field.setAccessible( true );
        ( field.getName, field.get( this ) );
    }
}

Scala故意让valvardef共享一个公共接口,所以你可以用后者替换前两者,而不会破坏任何代码——甚至不需要重新编译。

所以,虽然可以做您想做的事情,但它会导致脆弱的代码,做一些它不应该做的事情。

相关内容

  • 没有找到相关文章

最新更新