如何通过反射访问字段的值 (Scala 2.8)

发布于 2024-08-29 09:32:39 字数 410 浏览 5 评论 0原文

考虑以下代码:

class Foo(var name: String = "bar")

现在我尝试通过反射获取值及其正确类型:

val foo = new Foo
val field = foo.getClass.getDeclaredField("name")
field.setAccessible(true)
//This is where it doesn't work
val value = field.get(????)

我尝试了类似 field.get(foo) 的方法,但它只返回 java.lang.Object 而不是 String。基本上我需要正确的类型,因为我想调用它的方法(例如 toCharArray)。

建议的方法是什么?

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).

What is the suggested way to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

落在眉间の轻吻 2024-09-05 09:32:39

正如其他人提到的,反射方法返回 Object 因此您必须进行强制转换。您可能最好使用 Scala 编译器为字段访问创建的方法,而不是必须更改私有字段的可见性。 (我什至不确定名称私有字段是否保证与访问器方法的名称相同。)

val foo = new Foo
val method = foo.getClass.getDeclaredMethod("name")
val value = method.get(foo).asInstanceOf[String]

As others have mentioned, the reflection methods return Object so 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.)

val foo = new Foo
val method = foo.getClass.getDeclaredMethod("name")
val value = method.get(foo).asInstanceOf[String]
深府石板幽径 2024-09-05 09:32:39

getDeclaredFieldjava.lang.Class 的方法。

您必须将 foo.getDeclaredField("name") 更改为 foo.getClass.getDeclaredField("name") (或 classOf[Foo].getDeclaredField(" name")) 来获取字段。

您可以使用类 Field 中的 getType 方法获取类型,但它不会帮助您,因为它返回 Class[_]。鉴于您知道该类型是 String,您始终可以使用 field.get(foo).asInstanceOf[String] 转换返回的值

getDeclaredField is a method of java.lang.Class.

You have to change foo.getDeclaredField("name") to foo.getClass.getDeclaredField("name") (or classOf[Foo].getDeclaredField("name")) to get the field.

You can get the type with getType method in class Field but 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]

百善笑为先 2024-09-05 09:32:39

AFAIK,反射总是与对象一起工作,你必须自己投射结果。

AFAIK, reflection always work with Object, and you have to cast the results yourself.

海夕 2024-09-05 09:32:39

这是获取字段名列表及其案例类值的方法:
首先,使用反射,获取字段信息,如下 -

val TUPLE2_OF_FIELDNAME_TO_GETTERS = typeOf[<CLASS>].members
.filter(!_.isMethod)
.map(x => (x.name.toString, classOf[<CLASS>].getDeclaredMethod(x.name.toString.trim)))

如何使用它?

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)
    }
}

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)
    }
}
抹茶夏天i‖ 2024-09-05 09:32:39
foo.getClass.getDeclaredField("name").getString(foo)

如果你想避免 asInstanceOf 应该可以工作。 get* 可用于多种类型

foo.getClass.getDeclaredField("name").getString(foo)

should work if you want to avoid asInstanceOf. get* is available for various types

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文