Что такое immutable в java

Неизменяемые объекты в Java

Узнайте о неизменяемости и о том, как ее можно достичь в объекте Java.

1. Обзор

В этом уроке мы узнаем, что делает объект неизменяемым, как добиться неизменяемости в Java и какие преимущества дает это.

2. Что такое неизменяемый объект?

Это означает, что общедоступный API неизменяемого объекта гарантирует нам, что он будет вести себя одинаково в течение всего срока службы.

3. Последнее ключевое слово в Java

В Java переменные по умолчанию изменяемы, что означает, что мы можем изменить значение, которое они содержат|/.

Используя ключевое слово final при объявлении переменной, компилятор Java не позволит нам изменить значение этой переменной. Вместо этого он сообщит об ошибке во время компиляции:

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

Второй assertEquals завершится ошибкой, поскольку добавление элемента в список изменяет его размер, следовательно, он не является неизменяемым объектом.

4. Неизменяемость в Java

Теперь, когда мы знаем, как избежать изменений содержимого переменной, мы можем использовать ее для создания API неизменяемых объектов.

Создание API неизменяемого объекта требует от нас гарантии того, что его внутреннее состояние не изменится независимо от того, как мы используем его API.

Шагом вперед в правильном направлении является использование final при объявлении его атрибутов:

Обратите внимание, что Java гарантирует нам, что значение сумма не изменится, это относится ко всем переменным примитивного типа.

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

Как мы уже говорили ранее, для удовлетворения требований неизменяемого API наш класс Money имеет методы только для чтения.

5. Преимущества

6. Заключение

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

Источник

Объекты Stateless и Immutable

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в javaЧто такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в javaЧто такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в javaЧто такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в javaЧто такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в javaЧто такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

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

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

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

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

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

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

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

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

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

Источник

Immutable objects

Overview

To reap the benefits of immutability in Java, we created an annotation processor to easily create simple and consistent value objects. You can think of it as Guava’s Immutable Collections but for regular objects.

The core of Immutables is modelling. Good modelling is at the heart of creating good applications and services, and of good design in general. We feel proud to fill a gap in the area of modelling in the Java programming language, where conventional JavaBeans are insufficient.

Get started! Create an abstract value class and then add annotation to generate an immutable implementation class!

See sample generated code for an example of the code generated by the processor, or jump straight to the features!

Concepts

Abstract value type

An Abstract value type is a manually-written non-final (usually abstract) class or interface (or even annotation type) that defines the value type and is annotated with the org.immutables.value.Value.Immutable annotation. It may contain attributes and other metadata, as well as regular Java methods (and fields, if necessary). It is strongly recommended that abstract value types not introduce visible mutable state. Abstract value types are used as the source model for generated code. Get started!.

Attributes

Immutable implementation class

Features

Value

The annotation processor works by using annotated abstract value types as a model to generate immutable implementations. A generated implementation extends or implements an abstract value type. Classes don’t have to be abstract if they don’t define abstract accessor methods.

You can customize generated class names to have other prefixes than Immutable* or to have no prefix at all. See styles.

Nested abstract value types should be declared static if declared as inner classes (interfaces and annotations are implicitly static if nested).

You are not limited to using classes that you control. You can generate immutable implementation classes from the abstract types in other packages.

The @Value.Include annotation can be used on types and packages. This is most useful when you want to generate implementations of annotations to use with DI libraries such as Guice. Inclusion can be used in combination with @Value.Enclosing

Builder

By default, builders are generated for each immutable implementation class. Builders enable expressive construction of objects using named attribute initializers. Generally, builders compensate for the lack of named and optional constructor arguments in the Java language.

The build() method will fail if any mandatory attribute is omitted. Efficient bit masks are used internally to track which attributes are initialized!

The from method on builders is a much more sound and powerful alternative than having toBuilder() (or alike) on immutable values. For strict builders, from methods are not generated as they’re prone to errors. If value object inherits abstract accessor definitions from super-types, than it would be possible to copy from super-type instance (of any implementation type) those attributes which are applicable. Generated from method will have overloads for each super-type from which we can get attribute values we inherit. Just to note: types parameterized with generics and accessors with covariant return type overrides will be excluded from such «from super-type» initialization.

If a particular builder has become redundant due to the presence of a constructor, generation of the builder can be disabled using the @Value.Immutable(builder = false) annotation parameter.

For advanced use cases, it may be desirable to have builders that produce different types of objects but conform to the same interface, akin to the original Builder pattern. This is achievable by declaring a static nested class named «Builder» which will be extended by the generated builder.

An explicitly declared abstract «Builder» could specify all needed extends or implements declarations in addition to having convenience methods that will show up on the generated builder. However, special care should be taken in order to maintain the structural compatibility of declared builder super-types and generated builders to prevent compile-time type errors from appearing in the generated code.

Using «forwarding» factory methods and abstract builders, it is possible to hide the generated implementation type and its builder from the API. See this example.

Another structural customization for builders involves having a private immutable implementation class, hidden inside the builder, which is then generated as a standalone top-level builder class in the same package.

From version 2.0.17 onwards, it is possible to extend a [yet-to-be] generated builder to code in the following style:

For other structural and naming style customizations, see the style guide.

Strict Builder

No methods to reset collections are generated on strict builders. Additionally, no from method is generated. Those methods would be error-inducing in strict mode.

Note that it is not recommended to use @Value.Style directly on abstract value type; use it directly only during experimentation. The preferred method to use Style annotations is to create meta-annotations as described in the style guide.

Staged builder

The experimental new feature (since 2.3.2) allows you to enable generation of «staged builders» (aka «telescopic builders»). The mode is activated using @Value.Style(stagedBuilder = true) style attribute. A staged builder is a compile-time safe way to ensure that all required attributes are set. The API, composed of stage interfaces, forces initialization of mandatory attributes in stages, one by one, guiding via code-completion and making it impossible to even call build() before all are set. This guarantees that final build() call will not throw IllegalStateException for missing attributes. All remaining optional, nullable and collection attributes can be initialized on a final stage in any order. An addition, removal or change of the source order of the required attributes will cause compilation error for all builder usages and have to be corrected.

The price to pay for the additional compile-time safety is the increased count of java interfaces, generated per each required attribute. If staged builders are used extensively, this may lead to the increased memory/disc footprint and can affect class-loading time.

The staged builder mode also implies strict builder mode.

Constructor method

In order to generate a constructor method, certain attributes have to be annotated with org.immutables.value.Value.Parameter annotations.

You can optionally specify the ordering of parameters using order annotation attributes, to ensure that the order of constructor parameters does not differ between Java compilers (Java compilers do not necessarily preserve the order of declarations). Source ordering currently works for javac and Eclipse JDT compilers.

If you want to automatically turn all attributes into parameters to generate constructor, you could use styles for that, see tuple style pattern.

Plain public constructor

If there’s a need for plain public constructor instead of the factory method we can achieve it using styles by «renaming» of method to new :

Things to be aware of

Array, Collection and Map attributes

Following collection types enjoy built-in support for convenient usage:

Источник

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

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

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

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Источник

Immutable объекты в Java. Назначение и использование.

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

Что такое immutable объекты в Java

Это многофункциональные immutable (неизменяемые) объекты, которые можно применять в разных частях программы.

Например, это могут быть неизменяемые объекты в многопоточной среде для работы с данными. Также это могут быть сложные константы, которые помогают избежать излишнего использования памяти и перегрузки сборщика мусора (garbage collector). Отдельно стоит упомянуть иммутабельность при работе с коллекциями.

Основные параметры имутабельных классов (immutable classes)

Для того чтобы сказать, что класс является immutable (неизменяемым) он должен соотвествовать следующим критериям:

Практическое применение immutable объектов

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

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

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

Сложные константы

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

Например, класс Boolean и то как там устанавливаются состояния объекта:

Также пример с BigInteger:

В многопоточности (java tread safety)

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

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

Для этой цели можно использовать ThreadLocal класс. Ниже приведен пример использования локальных переменных для каждого отдельного потока.

В коллекциях

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

Представьте, что ключ будет изменяемым. Допустим вы положили объект в коллекцию с определенным ключем, например, «one». Далее в процессе объект ключа поменял хеш код и внутренние состояние. Буквально значение стало «two».

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

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

Строки (string) immutable

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

Строки пожалуй один из самых часто используемых классов. Ранее мы уже писали о String Pool, как хранятся строки в памыти, а также мы делали базовый обзор класса String в Java.

Как известно, сами строки не изменяемые (immutable). Каждый раз когда строка модифицируется, создается новый объект класса String. Поэтому для изменяемых строк сушествуют StringBuilder, StringBuffer.

А как обстоит дело со строковыми литерами? Если например меняется ссылка на строку, меняется ли и значение? Давайте рассмотрим пример:

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

Перечень часто используемых immutable классов в Java

Почти все классы обертки примитивных типов: Integer, String, Short, Boolean, BigInteger, BigDecimal и другие.

Дополнительно по теме, для тех кому лень читать:

Related posts

Распределение нагрузки с помощью NGINX в Spring Boot

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

Обзор работы с опционалами (Optional Java)

Что такое immutable в java. Смотреть фото Что такое immutable в java. Смотреть картинку Что такое immutable в java. Картинка про Что такое immutable в java. Фото Что такое immutable в java

Разновидности юнит тестов (unit testing). Основательный подход.

Leave a Comment Отменить ответ

Для отправки комментария вам необходимо авторизоваться.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *