Можно ли использовать gen-класс Clojure для создания частного финального поля?

Как создать класс Java с частным финальным полем в Clojure?

ClojureDocs для gen-класса говорят, что state поле будет общедоступным

: название штата

Если указано, будет создано открытое конечное поле экземпляра с заданным именем.

Итак, другими словами, у нас есть способ создать класс и после этого Java-объект с инкапсулированным состоянием?

0 ответов

@alexmiller недавно ответил на этот вопрос здесь

Короче нет. Как вы упомянули в документации, поля состояний gen-class будут общедоступными конечными полями. Тем не менее, это поле может быть (например), атом, который изменен в соответствии с методами реализации. В общем, мы не придаем большого значения инкапсуляции в Clojure - вместо этого мы предпочитаем делать вещи видимыми, но "безопасными" (через неизменяемость). По словам Рича из https://clojure.org/reference/datatypes, "инкапсуляция - это безумие".

gen-class не является DSL общего назначения для генерации всех возможных классов Java. Это инструмент для генерации классов в определенном стиле в соответствии с эстетикой Clojure.

Другой путь, однако, заключается в том, чтобы использовать deftype, который может иметь закрытые изменяемые поля, предоставляемые встроенными интерфейсами или протоколами. Поля deftype могут иметь мета ^:volatile-mutable или ^:unsynchronized-mutable, оба из которых станут частными полями.

Другие вопросы по тегам