Можно ли использовать 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, оба из которых станут частными полями.