解释 - 不涉及反思

Jat*_*tin 10 scala spray-json

我有一个非常简单的问题.这不仅适用于spray-json,而且我已经阅读过与argonaut和circe类似的说法.所以请赐教.

在spray-json中,我遇到了声明There is no reflection involved.我理解基于类的类方法,如果用户提供JsonFormat,那么一切都很好.但是这个说法在使用时也是如此DefaultJsonProtocol吗?

因为当我们你看看这个,你能看到的使用clazz.getMethods,clazz.getDeclaredFields等等.这不是反射的使用情况如何?虽然当然要归功于object#apply我们不需要担心使用反射在Java世界中设置不同.但至少阅读字段名称,我不明白如何反思过度.

Tra*_*own 17

我对spray-json并不是很熟悉,所以我不会捍卫它关于反射的主张,这似乎与ProductFormats你指出的部分不一致.

我更了解circe和Argonaut以及argonaut-shapedless和Play JSON,所有这些都使用一种反射来为案例类和其他用户定义类型派生编解码器.重要的是这些库不使用运行时反射 - 它们通过Scala的宏系统确定编译时所需的字段名称和其他信息.

通常当人们在Java或Scala的上下文中讨论"反射"时,它们意味着运行时反射,但宏也支持一种反射,所以当我个人谈论推导在这些库中如何工作时,我会小心指定没有涉及运行时反射.

您可以争辩说编译时反射(或元编程,或者您想要调用它的任何东西)比运行时反射要糟糕得多.它可能会使您的代码更加复杂,并且很容易被滥用,但它不会引入与运行时反射相同的脆弱性,并且它不会破坏您以与运行时反射相同的方式推理代码的能力.确实.如果你理解了宏做什么(这是一个很大的如果),你永远不会在运行时惊讶.

类型从根本上讲是在运行它们之前拒绝糟糕的潜在程序,并且在运行时对类型进行内省会使这一切变得混乱(正如Erik Osheim所说,"如果你在运行时遇到一个类型,就把它杀掉").另一方面,在编译时对类型的内省正是编译器所做的,而宏只是为程序员提供了一种参与该过程的简洁方式(或者至少相对干净,与编写编译器插件等相比). ).

避免运行时反射也可能有性能优势,但对我个人而言,这通常是次要问题 - 我讨厌运行时反射,因为我浪费了太多生命来调试可怕的Java代码,这些代码使用了很大程度上依赖于运行时反射的可怕Java库- 不是因为运行时反射可能会使我的程序稍慢.

这是一个非常啰嗦的方式,说你应该在这个上下文中读到"没有涉及反映",因为"没有涉及运行时反射"(即便如此,你不应该接受作者的话,我猜,考虑getMethods到喷雾中的所有东西).