2015-11-07 51 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