我有一个非常简单的问题。这不仅适用于 Spray-json,而且我读过 argonaut 和 circe 的类似声明。所以请赐教。
在 Spray-json 中,我遇到这样的声明:There is no reflection involved
。我理解基于类型类的方法,如果用户提供 JsonFormat 那么一切都很好。但是,当涉及到使用时,这种说法也成立吗?DefaultJsonProtocol
?
因为当我们你看着this https://github.com/spray/spray-json/blob/f185c5fb1d53f5399dbbb7229d7f7ae02971be20/src/main/scala/spray/json/ProductFormats.scala#L67,你可以看到用法clazz.getMethods
, clazz.getDeclaredFields
等等,这不就是反射的用法吗?虽然当然要感谢object#apply
我们不需要像 Java 世界中使用反射那样担心设置。但至少对于阅读字段名称,我不明白如何忽略反射。
我对spray-json不太熟悉,所以我不会捍卫它关于反射的主张,这似乎与ProductFormats
你指着。
我确实对 circe 和 Argonaut 以及 argonaut-shapeless 和 Play JSON 了解更多,所有这些都使用一种反射来派生案例类和其他用户定义类型的编解码器。重要的一点是这些库不使用runtime反射——它们通过 Scala 的宏系统在编译时确定所需的字段名称和其他信息。
一般来说,当人们在 Java 或 Scala 上下文中谈论“反射”时,他们指的是运行时反射,但宏也支持一种反射,因此当我个人谈论派生在这些库中如何工作时,我会尽量小心地指定没有runtime涉及反思。
您可以认为编译时反射(或元编程,或任何您想称呼的名称)比运行时反射要好得多。它可能会使您的代码更加复杂,并且很容易被滥用,但它不会引入与运行时反射相同的脆弱性,并且不会削弱您以与运行时反射相同的方式推理代码的能力做。如果您了解宏的作用(这是一个很大的if),在运行时你永远不会感到惊讶。
类型从根本上讲是在运行之前拒绝潜在的不良程序,而运行时对类型的自省会使这一切变得混乱(如埃里克·奥海姆 说 https://twitter.com/d6/status/364821225131872257,“如果你在运行时遇到一个类型,杀死它”)。另一方面,编译时对类型的自省正是编译器所做的,宏只是为程序员提供了一种参与该过程的干净方式(或者至少相对干净,与编写编译器插件等相比)。 )。
避免运行时反射也可能会带来性能上的好处,但对我个人来说,这通常是次要问题——我讨厌运行时反射,因为我浪费了太多的时间来调试可怕的 Java 代码,这些代码使用严重依赖运行时反射的可怕的 Java 库——不是因为运行时反射might让我的程序稍微慢一些。
这是一种非常冗长的方式,你应该在这种情况下将“不涉及反射”读作“不涉及运行时反射”(即使如此,我想你也不应该相信作者的话,鉴于这一切getMethods
Spray-json 中的内容)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)