Какие классы immutable java

Immutable Class in Java

In this tutorial, we’ll learn about Immutable Class and its benefits in thread-safety, caching and collections. We will also look at rules to create immutable classes and eventually we’ll write an Immutable Class from scratch in Java.

What is Immutable Class?

Immutable Class means that once an object is initialized from this Class, we cannot change the state of that object.

In other words, An immutable object can’t be modified after it has been created. When a new value is needed, the accepted practice is to make a copy of the object that has the new value.

Examples

In Java, All primitive wrapper classes (Integer, Byte, Long, Float, Double, Character, Boolean and Short) and String are immutable in nature.

String is the most popular Immutable Class known among developers. String object cannot be modified once initialized. Operations like trim(), substring(), replace(), toUpperCase(), toLowerCase() always return a new instance and don’t affect the current instance.

In the below example, s1.toUpperCase() returns new instance which need to assign back to s1, if you want s1 to refer to new uppercase instance.

String s1 = new String("CodingNConcepts"); String s2 = s1.toUpperCase(); System.out.println(s1 == s2); //false  s1 = s2; //assign back to s1  System.out.println(s1 == s2); //true 

Benefits of Immutable Class

Some of the key benefits of Immutable Class are:-

1. Mutable vs Immutable Object

A mutable object starts with one state (initial values of the instance variables). Each mutation of the instance variable takes the object to another state. This brings in the need to document all possible states a mutable object can be in. It is also difficult to avoid inconsistent or invalid states. Hence, all these makes a mutable object difficult to work with.

Whereas, immutable object have just one state, which is first and foremost benefit of Immutable Class.

2. Thread safety

Immutable objects are inherently thread-safe. They do not require synchronization. Since there is no way the state of an immutable object can change, there is no possibility of one thread observing the effect of another thread. We do not have to deal with the intricacies of sharing an object among threads (like locking, synchronization, making variables volatile etc.). Thus, we can freely share immutable objects. This is the easiest way to achieve thread safety.

3. Reusable/Cacheable

Immutable objects encourage to cache or store the frequently used instances rather than creating one each time. This is because two immutable instances with the same properties/values are equal.

Some examples of this being applied are as follows:-

Читайте также:  Тег input, атрибут required

Primitive wrapper classes
Creating primitive wrapper objects (Integer, Float, Double etc) using static factory method valueOf does not always return new wrapper instances. In case of Integer, they cache Integer values from -128 to 127 by default.

Integer oneV1 = new Integer(1); Integer oneV2 = new Integer(1); System.out.println(oneV1 == oneV2); //false  System.out.println(oneV1.equals(oneV2)); //true  oneV1 = Integer.valueOf(1); //returns cached instance  oneV2 = Integer.valueOf(1); //returns cached instance  System.out.println(oneV1 == oneV2); //true  System.out.println(oneV1.equals(oneV2)); //true 

BigInteger
BigInteger stores some common BigInteger values as instance variables.

 /**  * The BigInteger constant zero.  */ public static final BigInteger ZERO = new BigInteger(new int[0], 0); 

This reduces the memory footprint and the garbage collection costs.

4. Building blocks for Collections

The immutable objects make a great building block for Collections as compare to mutable objects. Let’s understand the problem we face with mutable objects in Collections.

First of all, we create a mutable Person class

class Person    String name;   public String getName()   return name;  >   public void setName(String name)   this.name = name;  >   @Override  public String toString()   return "Person < name: "+ name + " >";  > > 

Now let’s create some person objects to create Set of persons:-

Person person1 = new Person(); person1.setName("Adam");  Person person2 = new Person(); person2.setName("Ben");  SetPerson> setOfPerson = new HashSet<>(Arrays.asList(person1, person2)); System.out.println(setOfPerson);  person1.setName("Charlie"); System.out.println(setOfPerson); 

We wanted to create a Set of persons Adam and Ben but next part of the code has mutated the Adam to Charlie which is not intended. We will solve this problem by making an immutable class ImmutablePerson in subsequent part of the article.

As we saw that mutable objects can be mutated even if not intended, immutable objects make a great fit to be used as Keys of a Map, in Set, List, and other collections.

How to create Immutable Class?

In order to create an Immutable Class, you should keep following points in mind:-

  1. Declare the class as final so that it cannot be extended and subclasses will not be able to override methods.
  2. Make all the fields as private so direct access in not allowed
  3. Make all the fields as final so that value cannot be modified once initialized
  4. Provide no setter methods — setter methods are those methods which modify fields or objects referred to by fields.
  5. Initialize all the final fields through a constructor and perform a deep copy for mutable objects.
  6. If the class holds a mutable object:
    • Don’t provide any methods that modify the mutable objects.
    • Always return a copy of mutable object from getter method and never return the actual object reference.

Let’s apply all the above points and create our immutable class ImmutablePerson

ImmutablePerson.java
/**  * Immutable class should mark as final so it can not be extended.  * Fields should mark as private so direct access is not allowed.  * Fields should mark as final so value can not be modified once initialized.  **/ public final class ImmutablePerson    // String - immutable  private final String name;   // Integer - immutable  private final Integer weight;   // Date - mutable  private final Date dateOfBirth;   /**  * All the final fields are initialized through constructor  * Perform a deep copy of immutable objects  */  public ImmutablePerson(String name, Integer weight, Date dateOfBirth)  this.name = name;  this.weight = weight;  this.dateOfBirth = new Date(dateOfBirth.getTime());  >   /**********************************************  ***********PROVIDE NO SETTER METHODS *********  **********************************************/   /**  * String class is immutable so we can return the instance variable as it is  **/  public String getName()   return name;  >   /**  * Integer class is immutable so we can return the instance variable as it is  **/  public Integer getWeight()   return weight;  >   /**  * Date class is mutable so we need a little care here.  * We should not return the reference of original instance variable.  * Instead a new Date object, with content copied to it, should be returned.  **/  public Date getDateOfBirth()   return new Date(dateOfBirth.getTime());  >   @Override  public String toString()   return "Person < name: "+ name + ", weight: " + weight + ", dateOfBirth: " + new SimpleDateFormat("dd-MM-yyyy").format(dateOfBirth) + ">";  > > 

Now, Let’s create immutable person objects to create Set of persons:-

ImmutablePerson person1 = new ImmutablePerson("Adam", 55, new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2001"));  ImmutablePerson person2 = new ImmutablePerson("Ben", 50, new SimpleDateFormat("dd-MM-yyyy").parse("02-02-2002"));  SetImmutablePerson> setOfPerson = new HashSet<>(Arrays.asList(person1, person2)); System.out.println(setOfPerson); /** * ImmutablePerson do not provide setter methods, * no way to mutate name, weight, or date property fields. */ //person1.setName("Charlie"); //person1.setWeight(90); //person1.setDate(new SimpleDateFormat("dd-MM-yyyy").parse("03-03-2003"));  /** * getDateOfBirth() method returns new instance of date, * setYear() will not change value of person1's date field. */ Date person1Date = person1.getDateOfBirth(); person1Date.setYear(2020); System.out.println(setOfPerson); 

We see that we can not mutate the collection of ImmutablePerson once created.

Summary

In this tutorial, we learned about Immutable Class in Java and its benefits. Moreover, Immutable Class is frequently asked interview question to check your understanding on design pattern, immutable & mutable objects and final keyword.

What do you think?

As per Oracle Docs for Immutable Classes, Don’t allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.

Please note that we have marked the class as final and constructor as public in our ImmutablePerson class.

It is debatable. Should we use private constructor with static factory method to create instances? My view is we are restricting the instance creation by using private constructor, which is not a desired scenario for immutability.

What’s your thoughts on this? Please comment.

References:

Ashish Lahoti avatar

Ashish Lahoti is a Software Engineer with 12+ years of experience in designing and developing distributed and scalable enterprise applications using modern practices. He is a technology enthusiast and has a passion for coding & blogging.

Источник

Какие классы immutable java

Вопрос глуппый но задам. Сборщик мусора не сходит сума при работе с immutable? Наример нам приходится в программе таскать ‘с собой’ масивы строк и паралельно в них менять значения. Это жесть какая нагрузка на железо.

 public static void main(String[] args)

Вывод: I love Java I love Java Честно говоря, не понимаю, что удивительного в этом коде? Код же выполняется сверху вниз. А тут четверть статьи этому посвятили) Я так понимаю, что если я в конце в коде напишу: System.out.println(str1);, то вывод будет: I love Java I love Python Или я что-то не так понял?

Ведьмаку заплатите – чеканной монетой, чеканной монетой, во-о-оу Ведьмаку заплатите, зачтется все это вам

Всё что я должен понять из этой статьи: final для класса — класс нельзя наследовать, final для метода — метод нельзя переопределять, final для переменной — нельзя изменять первое присвоенное значение (сразу присваивать не обязательно), имя пишется капсом, слова через нижний пробел. Объекты всех классов обёрток, StackTrace, а также классы, используемые для создания больших чисел BigInteger и BigDecimal неизменяемые. Таким образом, при создании или изменении строки, каждый раз создаётся новый объект. Кратко о String Pool: Строки, указанные в коде литералом, попадают в String Pool (другими словами «Кэш строк»). String Pool создан, чтобы не создавать каждый раз однотипные объекты. Рассмотрим создание двух строковых переменных, которые указаны в коде литералом (без new String).

 String test = "literal"; String test2 = "literal"; 

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

Мало примеров и в целом, недосказано. Под конец вскользь упомянут String Pool, а что это не объясняется. Статья озаглавлена какFinal & Co, а по факту пару примеров по строкам, ну, такое. Это называется собирались пироги печь, а по факту лепёшки лепим. В любом случае, конечно, спасибо за труд. Но, гораздо лучше про строки написано здесь: Строки в Java (class java.lang.String). Обработка строк в Java. Часть I: String, StringBuffer, StringBuilder (более детальная статья на Хабре).

Получается мы не можем создать поле какого нибудь класса не константой public static final String name = «Амиго»; обязательно только так? => public static final String CHARACTER_NAME = «Амиго»; или можно написать и так и так?

«В прошлых лекциях мы видели простой пример наследования: у нас был родительский класс Animal, и два класса-потомка — Cat и Dog» ?! А была лекция о наследовании?! Может быть я где-то пропустил, поделитесь ссылкой, пожалуйста 🙂

Источник

Оцените статью