2015-11-07 236 views
8

我有一个非常简单的问题。这不仅仅是喷射式的,而且我已经读过与argonaut和circe相似的主张。所以请赐教。解释 - 无涉及

在喷雾JSON,我所遇到的声明说There is no reflection involved。我明白基于类型的方法,如果用户提供JsonFormat,那么一切都很好。但是这个说法在使用DefaultJsonProtocol时也是如此?

因为当我们看看this,你可以看到clazz.getMethods,clazz.getDeclaredFields等的用法。这不是反射的用法吗?虽然当然感谢object#apply,我们不需要担心在使用反射的Java世界中设置不同。但至少为了阅读字段名称,我不明白如何反思可能被忽视。

回答

16

我对spray-json不是很熟悉,所以我不会捍卫它关于反射的声明,这肯定与您指出的ProductFormats的部分不一致。

我知道更多关于circe和argonaut和argonaut-shapeless和Play JSON,所有这些都使用一种反射来派生casecs类和其他用户定义类型的编解码器。重要的一点是这些库不会使用反射 - 他们在编译时通过Scala的宏系统确定它们需要的字段名称和其他信息。

通常,当人们在Java或Scala的背景下讨论“反射”时,它们表示运行时反射,但宏也支持某种反射,所以当我个人谈论这些库中的派生如何工作时,我尝试请注意指定没有运行时间涉及到反射。

你可以争辩说编译时反射(或元编程,或任何你想将它命名)是要比运行时反射不那么糟糕。它可能会让你的代码更加复杂,并且很容易被滥用,但它并没有像运行时反射那样引入同样的脆弱性,也不会像运行时反射一样破坏你的代码推理能力确实。如果你了解宏的功能(如果是),那么在运行时你永远不会感到惊讶。

类型基本上是在运行它们之前拒绝不好的潜在程序,并且在运行时反省类型(如Erik Osheim says,“如果您在运行时遇到类型,请杀死它”)。另一方面,编译时对类型的反省正是编译器所做的事情,宏只是让程序员干脆参与到这个过程中(或者至少比编写编译器插件等要干净些)。 )。

避免运行时反射也可能会带来性能上的好处,但对于我个人而言,这通常是次要问题 - 我讨厌运行时反射,因为我已经浪费了太多时间来调试糟糕的Java代码,这些代码使用可怕的Java库严重依赖运行时反射 - 不是因为运行时反射可能使我的程序稍微慢一些。

这是一个非常冗长的方式,说你应该在这个上下文中看到“没有反射”,因为“没有涉及到运行时反射”(即使这样你也不应该把他作为作者)字,我想,给所有那些在喷雾json中的东西)。

+0

谢谢。我的直觉确实首先想到了宏。我甚至看到了李浩逸在json库中对垃圾运行时反射用法的推文。你可以说'与运行时反射相同的脆弱性'。这是否是因为人们必须派生类型并据此设置(特别是空值)引起关注的原因? – Jatin