Объяснение для - Отражение не включено
У меня очень простой вопрос. Это верно не только для Spray-JSON, но я читал похожие заявления с Argonaut и Circe. Поэтому, пожалуйста, просветите меня.
В спрей-джсон я сталкивался с высказыванием There is no reflection involved
, Я понимаю, для подхода, основанного на классах типов, если пользователь предоставляет JsonFormat, то все хорошо. Но верно ли это утверждение, когда дело доходит до использования DefaultJsonProtocol
?
Потому что, когда мы смотрим на это, вы можете увидеть использование clazz.getMethods
, clazz.getDeclaredFields
и т.д. Разве это не использование отражения? Хотя, конечно, благодаря object#apply
что нам не нужно беспокоиться об установке в отличие от Java-мира, использующего отражение. Но, по крайней мере, для чтения имен полей, я не понимаю, как отражение может быть пропущено.
1 ответ
Я не очень знаком с Spray-JSON, поэтому я не буду защищать его претензии по поводу рефлексии, которые определенно расходятся с частями ProductFormats
Вы указываете на.
Я знаю больше о circe, Argonaut и argonaut-shapeless, а также Play JSON, которые используют своего рода рефлексию для получения кодеков для классов case и других пользовательских типов. Важным моментом является то, что эти библиотеки не используют отражение во время выполнения - они определяют имена полей и другую информацию, которая им нужна во время компиляции, через макросистему Scala.
Обычно, когда люди говорят об "отражении" в контексте Java или Scala, они имеют в виду отражение во время выполнения, но макросы также поддерживают своего рода отражение, поэтому, когда я лично говорю о том, как происходит деривация в этих библиотеках, я стараюсь указать что нет никакого отражения во время выполнения.
Вы можете утверждать, что отражение во время компиляции (или метапрограммирование, или как вы хотите это называть) гораздо менее вредно, чем отражение во время выполнения. Это может сделать ваш код более сложным, и его очень легко злоупотреблять, но он не представляет такой же хрупкости, как отражение во время выполнения, и не подрывает вашу способность рассуждать о вашем коде так же, как отражение во время выполнения делает. Если вы понимаете, что делает макрос (что очень важно), вы никогда не удивитесь во время выполнения.
Типы в основном сводятся к отказу от плохих потенциальных программ перед их запуском, а самоанализ типов во время выполнения запутывает все это (как говорит Эрик Осхейм: "Если вы встретите тип во время выполнения, убейте его"). С другой стороны, самоанализ типов во время компиляции - это именно то, что делают компиляторы, а макросы просто дают вам как программисту чистый способ участия в этом процессе (или, по крайней мере, относительно чистый по сравнению с написанием плагинов компилятора и т. Д.).).
Может также быть преимущество в производительности, позволяющее избежать рефлексии во время выполнения, но лично для меня это, как правило, второстепенная проблема - я ненавижу рефлексию во время выполнения, потому что я потратил слишком много времени на отладку ужасного кода Java, который использует ужасные библиотеки Java, которые сильно зависят от отражения во время выполнения - не потому, что отражение во время выполнения может сделать мои программы несколько медленнее.
Это все очень многословный способ сказать, что вы должны читать "здесь нет никакого отражения" в этом контексте, как "нет никакого отражения во время выполнения" (и даже тогда вы не должны воспринимать автора как слово, я полагаю учитывая все это getMethods
вещи в спрей-джон).