scala:java.lang.reflect.Field的可序列化替代方法

阿米尔

假设User有一个案例类,其中包含有关用户的信息:

case class User(name: String, age: Int)

给定一个字段名称(例如"name""age"),我想返回一个提取该字段函数(无需再次解析该字段名称)。简而言之,我需要这样做:

val u = User(name = "john",age = 44)
val func = extractFunctionFromFieldName("name") // returns func: User => Any
func(u) // return "john"

阅读有关反射的内容后,我得到了类似的工作:

def extractFunctionFromFieldName(s: String): User => Any = {
  val f = classOf[User].getDeclaredField(s)
  f.setAccessible(true)
  u: User => f.get(u)
}

问题在于此功能不可序列化,因为java.lang.reflect.Field不可序列化。

有什么建议或选择吗?

备注/更多背景:

  • 字段列表远不止于此,{name,age}而且还在不断增长。这就是为什么我要避免硬编码
  • 使用productElement应该没有序列化问题,因为字段已被数字替换。但我知道不能保证产品元素的顺序。
  • 顺便说一句,我需要它可序列化,因为我将其与apache spark一起使用。
阿列克谢·罗曼诺夫(Alexey Romanov)

使用productElement应该可以解决序列化问题,因为字段已被数字替换。但我知道不能保证产品元素的顺序。

有。对于案例类,它们的顺序与参数相同。

或者,您可以创建一个类,该类仍然可以是一个函数(这里有点通用;如果不需要,更改为User仅使用它应该很容易):

case class ExtractField[T](s: String)(implicit t: ClassTag[T]) extends (T => Any) {
  @transient lazy val f = {
    val f = t.runtimeClass.getDeclaredField(s)
    f.setAccessible(true)
    f
  }

  def apply(x: T) = f.get(x)
}

这将仅在第一次应用该字段时初始化该字段,因此可以在将其反序列化一次后多次应用而无需重复getDeclaredField调用。

最初我没有注意到这已经是问题所必需的,因此我最初提供的另一种解决方案不适用:您可以f在函数内部移动(在这种情况下,f当您创建函数对象并“捕获”时已经知道了)它,这就是为什么必须对其进行序列化的原因):

def extractFunctionFromFieldName(s: String): User => Any = { u: User => 
  val f = classOf[User].getDeclaredField(s)
  f.setAccessible(true)
  f.get(u)
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

了解java.lang.reflect.InvocationHandler的invoke方法的“代理”参数

来自分类Dev

了解java.lang.reflect.InvocationHandler的invoke方法的“代理”参数

来自分类Dev

Scala TypeTag到java.lang.reflect.Type

来自分类Dev

如何从Scala类型获取java.lang.reflect.Type?

来自分类Dev

java.lang.NoClassDefFoundError:scala / reflect / api / TypeCreator

来自分类Dev

java.lang.ClassNotFoundException:scala.reflect.api.TypeCreator

来自分类Dev

如何从Scala类型获取java.lang.reflect.Type?

来自分类Dev

Scala TypeTag到java.lang.reflect.Type

来自分类Dev

Android中的java.lang.reflect.invocationtargetException

来自分类Dev

java.lang.reflect.Array的性能

来自分类Dev

尝试在空对象引用上调用虚拟方法'java.lang.Class java.lang.reflect.Field.getType()'

来自分类Dev

Roboelectric java.lang.RuntimeException:java.lang.reflect.InvocationTargetException

来自分类Dev

为什么不使用java.util.List检查java.lang.reflect.Field的实例

来自分类Dev

Firebase API 初始化失败,java.lang.reflect.InvocationTargetException

来自分类Dev

Firebase API 初始化失败.java.lang.reflect.InvocationTargetException

来自分类Dev

应用程序启动方法java.lang.reflect.InvocationTargetException中的异常

来自分类Dev

BigSheets-java.io.IOException:java.lang.reflect.UndeclaredThrowableException

来自分类Dev

为什么显示“ java.lang.reflect.InvocationTargetException”

来自分类Dev

使用java.lang.reflect.Type检查实例

来自分类Dev

显示错误原因:java.lang.reflect.InvocationTargetException

来自分类Dev

Javassist:将CtMethod转换为java.lang.reflect.Method

来自分类Dev

获取java.lang.reflect.Type的简单代码

来自分类Dev

从TextField获取值时java.lang.reflect.InvocationTargetException-Javafx

来自分类Dev

java.lang.reflect.Proxy:巨大的异常堆栈跟踪

来自分类Dev

什么是`4161`在java.lang.reflect.Method中修改的平均

来自分类Dev

投java.lang.reflect.Method中的功能接口

来自分类Dev

会议室DB:java.lang.reflect.InvocationTargetException

来自分类Dev

如何修复/解决java.lang.reflect.InvocationTargetException

来自分类Dev

签名的jar抛出java.lang.reflect.InvocationTargetException

Related 相关文章

  1. 1

    了解java.lang.reflect.InvocationHandler的invoke方法的“代理”参数

  2. 2

    了解java.lang.reflect.InvocationHandler的invoke方法的“代理”参数

  3. 3

    Scala TypeTag到java.lang.reflect.Type

  4. 4

    如何从Scala类型获取java.lang.reflect.Type?

  5. 5

    java.lang.NoClassDefFoundError:scala / reflect / api / TypeCreator

  6. 6

    java.lang.ClassNotFoundException:scala.reflect.api.TypeCreator

  7. 7

    如何从Scala类型获取java.lang.reflect.Type?

  8. 8

    Scala TypeTag到java.lang.reflect.Type

  9. 9

    Android中的java.lang.reflect.invocationtargetException

  10. 10

    java.lang.reflect.Array的性能

  11. 11

    尝试在空对象引用上调用虚拟方法'java.lang.Class java.lang.reflect.Field.getType()'

  12. 12

    Roboelectric java.lang.RuntimeException:java.lang.reflect.InvocationTargetException

  13. 13

    为什么不使用java.util.List检查java.lang.reflect.Field的实例

  14. 14

    Firebase API 初始化失败,java.lang.reflect.InvocationTargetException

  15. 15

    Firebase API 初始化失败.java.lang.reflect.InvocationTargetException

  16. 16

    应用程序启动方法java.lang.reflect.InvocationTargetException中的异常

  17. 17

    BigSheets-java.io.IOException:java.lang.reflect.UndeclaredThrowableException

  18. 18

    为什么显示“ java.lang.reflect.InvocationTargetException”

  19. 19

    使用java.lang.reflect.Type检查实例

  20. 20

    显示错误原因:java.lang.reflect.InvocationTargetException

  21. 21

    Javassist:将CtMethod转换为java.lang.reflect.Method

  22. 22

    获取java.lang.reflect.Type的简单代码

  23. 23

    从TextField获取值时java.lang.reflect.InvocationTargetException-Javafx

  24. 24

    java.lang.reflect.Proxy:巨大的异常堆栈跟踪

  25. 25

    什么是`4161`在java.lang.reflect.Method中修改的平均

  26. 26

    投java.lang.reflect.Method中的功能接口

  27. 27

    会议室DB:java.lang.reflect.InvocationTargetException

  28. 28

    如何修复/解决java.lang.reflect.InvocationTargetException

  29. 29

    签名的jar抛出java.lang.reflect.InvocationTargetException

热门标签

归档