如何通过反射访问字段的值 (Scala 2.8)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2658060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access a field's value via reflection (Scala 2.8)
提问by soc
Consider the following code:
考虑以下代码:
class Foo(var name: String = "bar")
Now i try to get the value and the correct type of it via reflection:
现在我尝试通过反射获取值和正确的类型:
val foo = new Foo
val field = foo.getClass.getDeclaredField("name")
field.setAccessible(true)
//This is where it doesn't work
val value = field.get(????)
I tried things like field.get(foo), but that just returns an java.lang.Object but no String. Basically I need the correct type, because I want to invoke a method on it (e. g. toCharArray).
我尝试过诸如 field.get(foo) 之类的东西,但它只返回一个 java.lang.Object 而不是 String。基本上我需要正确的类型,因为我想调用它的方法(例如 toCharArray)。
What is the suggested way to do that?
建议的方法是什么?
采纳答案by Ben Lings
As others have mentioned, the reflection methods return Objectso you have to cast. You may be better using the method that the Scala compiler creates for field access rather than having to change the visibility of the private field. (I'm not even sure if the name private field is guaranteed to be the same as that of the accessor methods.)
正如其他人所提到的,反射方法会返回,Object因此您必须进行转换。您可能会更好地使用 Scala 编译器为字段访问创建的方法,而不必更改私有字段的可见性。(我什至不确定名称私有字段是否保证与访问器方法的名称相同。)
val foo = new Foo
val method = foo.getClass.getDeclaredMethod("name")
val value = method.get(foo).asInstanceOf[String]
回答by gerferra
getDeclaredFieldis a method of java.lang.Class.
getDeclaredField是一种方法java.lang.Class。
You have to change foo.getDeclaredField("name")to foo.getClass.getDeclaredField("name")(or classOf[Foo].getDeclaredField("name")) to get the field.
您必须更改foo.getDeclaredField("name")为foo.getClass.getDeclaredField("name")(或classOf[Foo].getDeclaredField("name")) 才能获得该字段。
You can get the type with getTypemethod in class Fieldbut it won't help you because it returns Class[_]. Given than you know that the type is a String you can always cast the value returned using field.get(foo).asInstanceOf[String]
您可以使用类中的getType方法获取类型,Field但它不会帮助您,因为它返回Class[_]. 鉴于您知道该类型是一个字符串,您始终可以使用以下方法转换返回的值field.get(foo).asInstanceOf[String]
回答by Daniel C. Sobral
AFAIK, reflection always work with Object, and you have to cast the results yourself.
AFAIK,反射总是与对象一起工作,你必须自己投射结果。
回答by Sruthi Poddutur
This is how one can get list of fieldnames and its value of a case class:
First, using reflection, get fields info as follows -
这是获取字段名称列表及其案例类值的方法:
首先,使用反射,获取字段信息,如下所示 -
val TUPLE2_OF_FIELDNAME_TO_GETTERS = typeOf[<CLASS>].members
.filter(!_.isMethod)
.map(x => (x.name.toString, classOf[<CLASS>].getDeclaredMethod(x.name.toString.trim)))
How to use it?
如何使用它?
getFieldNameAndValue(obj: <CLASS>): Seq[(String, String)] {
var output = Seq[(String, String)]()
for(fieldToGetter <- TUPLE2_OF_FIELDNAME_TO_GETTERS) {
val fieldNameAsString = fieldToGetter._1
val getter = fieldToGetter._2
val fieldValue = getter.invoke(obj).toString
output += (fieldName, fieldValue)
}
}

