объекты какого класса являются иммутабельными java

Иммутабельность в Java

Привет, Хабр. В преддверии скорого старта курса «Подготовка к сертификации Oracle Java Programmer (OCAJP)» подготовили для вас традиционный перевод материала.

Приглашаем также всех желающих поучаствовать в открытом демо-уроке «Конструкторы и блоки инициализации». На этом бесплатном вебинаре мы:
— Разберём конструктор на запчасти
— Определим финалистов (финальные переменные)
— Наведём порядок (инициализации)

9fcebc3c12c2ad4ce83d63daef66f95f

Иммутабельный (неизменяемый, immutable) класс — это класс, который после инициализации не может изменить свое состояние. То есть если в коде есть ссылка на экземпляр иммутабельного класса, то любые изменения в нем приводят к созданию нового экземпляра.

Чтобы класс был иммутабельным, он должен соответствовать следующим требованиям:

Должен быть объявлен как final, чтобы от него нельзя было наследоваться. Иначе дочерние классы могут нарушить иммутабельность.

Все поля класса должны быть приватными в соответствии с принципами инкапсуляции.

Для корректного создания экземпляра в нем должны быть параметризованные конструкторы, через которые осуществляется первоначальная инициализация полей класса.

Для исключения возможности изменения состояния после инстанцирования, в классе не должно быть сеттеров.

Для полей-коллекций необходимо делать глубокие копии, чтобы гарантировать их неизменность.

Иммутабельность в действии

Начнем со следующего класса, который, на первый взгляд, выглядит иммутабельным:

Теперь посмотрим на него в действии.

Очевидно, что мы хотим запретить добавление элементов в коллекцию, поскольку это изменение состояния объекта, то есть отсутствие иммутабельности.

Хотя использование иммутабельных объектов дает преимущества, но их использование не всегда оправдано. Обычно нам нужно как создавать объекты, так и модифицировать их для отражения изменений, происходящих в системе.

То есть нам нужно изменять данные, и нелогично создавать новые объекты при каждом изменении, так как это увеличивает используемую память, а мы хотим разрабатывать эффективные приложения и оптимально использовать ресурсы системы.

Иммутабельность строк в Java

Например, в классе String есть методы для получения символов, выделения подстрок, поиска, замены и многие другие. Как и другие классы-обертки в Java (Integer, Boolean и т.д.), класс String является иммутабельным.

Иммутабельность строк дает следующие преимущества:

Для строк можно использовать специальную область памяти, называемую «пул строк». Благодаря которой две разные переменные типа String с одинаковым значением будут указывать на одну и ту же область памяти.

Строки отличный кандидат для ключей в коллекциях, поскольку они не могут быть изменены по ошибке.

Чувствительные данные, такие как имена пользователей и пароли, нельзя изменить по ошибке во время выполнения, даже при передаче ссылок на них между разными методами.

Подробнее о курсе «Подготовка к сертификации Oracle Java Programmer (OCAJP)».

Смотреть вебинар «Конструкторы и блоки инициализации».

Источник

Иммутабельность в JavaScript

image loader

Что такое иммутабельность

Неизменяемым (англ. immutable) называется объект, состояние которого не может быть изменено после создания. Результатом любой модификации такого объекта всегда будет новый объект, при этом старый объект не изменится.

Речь не идет о глубоком копировании: если объект имеет вложенную структуру, то все вложенные объекты, не подвергшиеся модификации, будут переиспользованы.

В памяти объекты будут представлены следующим образом:

Читайте также:  на какой неделе беременности эмбрион прикрепляется к стенке матки

image loader

Правда или ложь? Иммутабельные данные в JavaScript

Простое и быстрое отслеживание изменений

Эту возможность активно используют в связке с популярным нынче VirtualDOM (React, Mithril, Riot) для ускорения перерисовки web-страниц.

Внутри объектов bounds и style.font операции сравнения производить не нужно, так как они иммутабельны, и ссылки на них не изменились.

Безопаснее использовать и легче тестировать

Нередки случаи, когда переданные в функцию данные могут быть случайно испорчены, и отследить такие ситуации очень сложно.

Здесь иммутабельные данные спасли бы ситуацию. Функция sort была бы запрещена.

Или вернула бы новый отсортированный массив, не меняя старый:

Больший расход памяти

Каждый раз при модификации иммутабельного объекта создается его копия с необходимыми изменениями. Это приводит к большему расходу памяти, чем при работе с обычным объектом. Но поскольку иммутабельные объекты никогда не меняются, они могут быть реализованы с помощью стратегии, называемой «общие структуры» (structural sharing), которая порождает гораздо меньшую издержку в затратах на память, чем можно было бы ожидать. В сравнении со встроенными массивами и объектами издержка все еще будет существовать, но она будет иметь фиксированную величину и обычно может компенсироваться другим преимуществами, доступными благодаря неизменяемости.

Легче кешировать (мемоизировать)

В большинстве случаев кешировать легче не станет. Этот пример прояснит ситуацию:

Несмотря на то, что data.value из первого шага не отличается от data.value из последнего шага, сам объект data уже другой, и ссылка на него тоже изменилась.

Отсутствие побочных эффектов

Гарантий того, что функция станет чистой, или что у нее будут отсутствовать побочные эффекты — нет.

Ускорение кода. Больше простора для оптимизаций

Thread safety

JavaScript — однопоточный, и говорить тут особо не о чем. Многие путают асинхронность и многопоточность — это не одно и тоже.
По умолчанию есть только один поток, который асинхронно обслуживает очередь сообщений.
В браузере для многопоточности есть WebWorkers, но единственное возможное общение между потоками осуществляется через отправку строк или сериализованного JSON; к одним и тем же переменным из разных воркеров обратиться нельзя.

Возможности языка

Ключевое слово const

Использование const вместо var или let не говорит от том, что значение является константой или что оно иммутабельно (неизменяемо). Ключевое слово const просто указывает компилятору следить за тем, что переменной больше не будет присвоено никаких других значений.

В случае использования const современные JavaScript-движки могут выполнить ряд дополнительных оптимизаций.

Object.freeze

Метод Object.freeze замораживает объект. Это значит, что он предотвращает добавление новых свойств к объекту, удаление старых свойств из объекта и изменение существующих свойств или значения их атрибутов перечисляемости, настраиваемости и записываемости. В сущности, объект становится эффективно неизменным. Метод возвращает замороженный объект.

Сторонние библиотеки

Seamless-Immutable

Библиотека предлагает иммутабельные структуры данных, обратно совместимые с обычными массивами и объектами. То есть доступ к значениям по ключу или по индексу не будет отличаться от привычного, будут работать стандартные циклы, а также все это можно использовать в связке со специализированными высокопроизводительными библиотеками для манипуляций с данными, вроде Lodash или Underscore.

Некоторые браузеры, например Safari, имеют проблемы с производительностью при работе с замороженными при помощи Object.freeze объектами, так что в production сборке это отключено для увеличения производительности.

Immutable.js

Благодаря продвижению со стороны Facebook эта библиотека для работы с иммутабельными данными стала самой распространенной и популярной среди web-разработчиков. Она предоставляет следующие неизменяемые структуры данных:

Библиотека, которая привносит персистентные структуры данных из ClojureScript (Lists, Vectors, Maps и т.д.) в JavaScript.

Отличия от Immutable.js:

Проблемы при разработке, с которыми вы столкнетесь

Речь пойдет об использовании Immutable.js (с Mori все примерно также). В случае работы с Seamless-Immutable таких проблем у вас не возникнет из-за обратной совместимости с нативными структурами JavaScript.

Читайте также:  на каком расстоянии отверстия в мангале сверлятся

Работа с серверным API

Дело в том, что в большинстве случаев серверное API принимает и возвращает данные в формате JSON, который соответствует стандартным объектам и массивам из JavaScript. Это значит, что нужно будет каким-то образом преобразовывать Immutable-данные в обычные и наоборот.

Immutable.js для конвертации обычных данных в иммутабельные предлагает следующую функцию:

где с помощью функции reviver можно добавлять собственные правила преобразования и управлять существующими.

Предположим, серверное API вернуло нам следующий объект:

Удобнее всего такой объект будет представить как OrderedMap. Напишем соответствующий reviver :

Предположим, нам нужно изменить данные и отправить их обратно на сервер:

Immutable.js для конвертации иммутабельных данных в обычные предлагает следующую функцию:

Можно, конечно, использовать при разработке только List и Map, но тогда зачем же все остальное? И в чем плюсы использования конкретно Immutable.js?

Иммутабельность везде

Если проект раньше работал с нативными структурами данных, то легко перейти на иммутабельные не получится. Придется переписывать весь код, который хоть как-то взаимодействует с данными.

Сериализация/Десериализация

То есть абсолютно бесполезны для сериализации/десериализации.

Существует сторонняя библиотека transit-immutable-js. Пример ее использования:

Производительность

Для тестирования производительности были написаны бенчмарки. Чтобы запустить их у себя, выполните команды:

Результаты бенчмарков можно увидеть на графиках (repeats / ms). Чем больше время выполнения, тем хуже результат.

При чтении самыми быстрыми оказались нативные структуры данных и Seamless-immutable.

image loader

При записи самым быстрым оказался Mori. Seamless-immutable показал наихудший результат.

image loader

Заключение

Эта статья будет полезна JavaScript-разработчикам, столкнувшимся с необходимостью использовать иммутабельные данные в своих приложениях для повышения производительности. В частности, это касается frontend-разработчиков, которые работают с фреймворками, использующими VirtualDOM (React, Mithril, Riot), а также Flux/Redux решения.

Источник

Объекты Stateless и Immutable

facebooktwittertumblrfacebooktwittertumblr

Привет! Это статья о двух типах объектов в Java:

Данные объекты используются в многопоточной среде для того, чтобы быть уверенными что эти объекты не будут изменены каким-либо другим потоком. То есть зафиксировали состояние один раз и все. Иначе нам бы пришлось думать о том как синхронизировать доступ к этим объектам из разных потоков. А это замедляет работу программы.

Что такое stateless объект?

Так что такое «состояние»?

Обычно каждый объект имеет какие-то изменяемые переменные внутри. Например, мы создаем объект Car, и задаем ему:

auto 3309967 640

auto 3309967 640

1

Объект без состояния

Обычно мы создаем объекты так, что они хранят много переменных. И эти переменные изменяются, меняя состояние объекта.

Но это обычно.

Источник

immutable-объекты и многопоточность

Доброго дня, уважаемые гуру Java. Анализирую вопросы, которые задают на собеседованиях. Пытаюсь более детально разобраться с темой immutable-объектов. К сожалению, те ресурсы, которые предлагает «Google» дают лишь очень общую информацию в стиле «immutable-объекты, это те объекты, которые не могут быть изменены в программе. Для того, чтобы объект был immutable используйте модификатор final». Как энциклопедические знания такое конечно можно сказать, на собеседовании, но думаю, там хотят слышать понимание более глубоких принципов. Кроме того, хочу написать мини-проект для лучшего понимания.

Можете ли Вы пояснить на примерах или подсказать адекватные источники, где раскрыты рекомендации по использованию неизменяемых объектов в контексте многопоточности?

2 ответа 2

Для начала, есть разница между immutable-объектом (то есть, неизменяемым), и final-ссылкой.

В случае же immutable-объекта объект после окончания конструктора не изменяется вообще. Одного лишь модификатора final для этого недостаточно, необходимо, чтобы все подбъекты были тоже неизменяемыми. Вы в принципе можете держать внутри ссылку на изменяемый объект, но обращаться с ним так, чтобы он не менялся.

Использование неизменяемых объектов даёт много выгод. Например, о таком объекте намного легче судить в ситуации, когда во многих частях программы есть ссылка на него (для изменяемого объекта, любая часть программы может вызвать мутирующую функцию в практически любой момент времени и из любого потока).

Читайте также:  в какие конструктивные командные роли можно перевести деструктивную командную роль саботажник

Но то, что для нас важно в контексте вопроса — неизменяемые объекты не требуют синхронизации при многопоточном доступе. Вот собственно и вся рекомендация: используйте неизменяемые объекты, и вам не придётся думать о том, что нужно, а что не нужно синхронизировать. Единственная возможная проблема — если вы внутри ещё не отработавшего конструктора публикуете ссылку на объект, через которую к нему может получить доступ кто-нибудь ещё, и увидеть объект в изменяющемся состоянии! (Это бывает не так уж и редко. Например, иногда программист хочет добавить объект в конструкторе в коллекцию всех объектов данного типа.)

Следует различать действительно неизменяемые объекты, и объекты, имеющие лишь интерфейс «только для чтения». При чтении объект тем не менее может менять свою внутреннюю структуру (например, кэшировать самый свежий запрос данных). Такие объекты не являются в строгом смысле неизменяемыми, и не могут быть использованы из разных потоков без предосторожностей. (Поэтому, если ваш объект включает другие объекты, убедитесь, что документация гарантирует их неизменяемость!)

Источник

Иммутабельность в Java

Привет, Хабр. В преддверии скорого старта курса «Подготовка к сертификации Oracle Java Programmer (OCAJP)» подготовили для вас традиционный перевод материала.

Приглашаем также всех желающих поучаствовать в открытом демо-уроке «Конструкторы и блоки инициализации». На этом бесплатном вебинаре мы:
— Разберём конструктор на запчасти
— Определим финалистов (финальные переменные)
— Наведём порядок (инициализации)

image loader

Иммутабельный (неизменяемый, immutable) класс — это класс, который после инициализации не может изменить свое состояние. То есть если в коде есть ссылка на экземпляр иммутабельного класса, то любые изменения в нем приводят к созданию нового экземпляра.

Чтобы класс был иммутабельным, он должен соответствовать следующим требованиям:

Должен быть объявлен как final, чтобы от него нельзя было наследоваться. Иначе дочерние классы могут нарушить иммутабельность.

Все поля класса должны быть приватными в соответствии с принципами инкапсуляции.

Для корректного создания экземпляра в нем должны быть параметризованные конструкторы, через которые осуществляется первоначальная инициализация полей класса.

Для исключения возможности изменения состояния после инстанцирования, в классе не должно быть сеттеров.

Для полей-коллекций необходимо делать глубокие копии, чтобы гарантировать их неизменность.

Иммутабельность в действии

Начнем со следующего класса, который, на первый взгляд, выглядит иммутабельным:

Теперь посмотрим на него в действии.

Очевидно, что мы хотим запретить добавление элементов в коллекцию, поскольку это изменение состояния объекта, то есть отсутствие иммутабельности.

Хотя использование иммутабельных объектов дает преимущества, но их использование не всегда оправдано. Обычно нам нужно как создавать объекты, так и модифицировать их для отражения изменений, происходящих в системе.

То есть нам нужно изменять данные, и нелогично создавать новые объекты при каждом изменении, так как это увеличивает используемую память, а мы хотим разрабатывать эффективные приложения и оптимально использовать ресурсы системы.

Иммутабельность строк в Java

Например, в классе String есть методы для получения символов, выделения подстрок, поиска, замены и многие другие. Как и другие классы-обертки в Java (Integer, Boolean и т.д.), класс String является иммутабельным.

Иммутабельность строк дает следующие преимущества:

Для строк можно использовать специальную область памяти, называемую «пул строк». Благодаря которой две разные переменные типа String с одинаковым значением будут указывать на одну и ту же область памяти.

Строки отличный кандидат для ключей в коллекциях, поскольку они не могут быть изменены по ошибке.

Чувствительные данные, такие как имена пользователей и пароли, нельзя изменить по ошибке во время выполнения, даже при передаче ссылок на них между разными методами.

Источник

admin
Своими руками
Adblock
detector