我有一个非常简单的问题。这不仅适用于spray-json,而且我已经阅读过与argonaut和circe类似的说法。所以请赐教。
在spray-json中,我遇到了There is no reflection involved
的声明。我理解基于类的类方法,如果用户提供JsonFormat,那么一切都很好。但在使用DefaultJsonProtocol
?
因为当我们查看this时,您可以看到clazz.getMethods
,clazz.getDeclaredFields
的使用情况等等。这不是反射的用法吗?虽然当然要感谢object#apply
我们不需要担心在Java世界中使用反射进行设置。但至少要阅读字段名称,我不明白如何反思过度。
答案 0 :(得分:16)
我对spray-json不太熟悉,所以我不会捍卫它关于反射的主张,这似乎与你指出的ProductFormats
部分不一致。 / p>
我对circe和Argonaut以及argonaut-shapedless和Play JSON有更多了解,所有这些都使用一种反射来为案例类和其他用户定义类型派生编解码器。重要的是,这些库不使用运行时反射 - 它们通过Scala的宏系统确定编译时所需的字段名称和其他信息。
一般来说,当人们谈论&#34;反思&#34;在Java或Scala的上下文中,它们意味着运行时反射,但是宏也支持一种反射,所以当我个人谈论派生如何在这些库中工作时,我会小心地指出那里没有<涉及em> runtime 反射。
您可以认为编译时反射(或元编程,或者您想要调用它的任何东西)比运行时反射要糟糕得多。这可能会使您的代码更加复杂,并且很容易被滥用,但它并没有引入与运行时反射相同的脆弱性,并且它不会破坏您推理自己的能力。代码与运行时反射的方式相同。如果您了解宏的作用(如果是一个很大的),那么您在运行时永远不会感到惊讶。
类型从根本上说是在运行它们之前拒绝糟糕的潜在程序,并且在运行时对类型进行内省会使这一切变得混乱(如Erik Osheim says,&#34;如果在运行时遇到类型,请将其删除&# 34)。另一方面,在编译时对类型的内省正是编译器所做的,而宏只是为程序员提供了一种参与该过程的简洁方法(或者至少相对干净,与编写编译器插件等相比)。 )。
避免运行时反射可能也有性能优势,但对我个人而言,这通常是次要问题 - 我讨厌运行时反射,因为我浪费了太多的生命来调试使用的可怕的Java代码可怕的Java库很大程度上依赖于运行时反射 - 不是因为运行时反射可能使我的程序稍慢。
这是一个非常冗长的方式,说你应该阅读&#34;没有涉及反思&#34;在这种情况下,&#34;不涉及运行时反射&#34; (即使那样,考虑到喷雾json中所有getMethods
的东西,你不应该把作者听从他们的话。