Create an immutable object of Java

  • 2021-12-11 17:48:16
  • OfStack

Directory 01, What Are Immutable Classes 02, Common Immutable Classes 1) Need for Constant Pool 2) Need for hashCode 3) Thread Safety 03, Hand-to-Hand Immutable Classes 04, Summary

Foreword:

Why String Yes immutable Class (immutable object)? I want to study it and wonder why it is immutable. This strong desire is like studying the vast starry sky. However, I have no choice but to have limited skills, and I always feel that seeing flowers in the fog is separated by one floor. Brother 2, your article is always full of interest. I think 1 will be able to say clearly, and I will be able to see clearly. Can I write 1 next?

https://github.com/itwanger/toBeBetterJavaer

01. What is an immutable class

If the state of an object of a class will not be changed after it is created by the constructor, then it is an immutable ( immutable ) class. The assignment of all its member variables is only done in the constructor and does not provide any setter Method for external classes to modify.

Remember the tomb of the little dragon girl in the Condor Heroes? With that loud noise, the only passage was mercilessly closed. Don't take that secret passage seriously, I just say this to open your imagination and give you a more intuitive impression of immutable classes.

Since multithreading, productivity has been infinitely magnified, and all programmers love it because the powerful hardware capabilities are fully utilized. But at the same time, all programmers are afraid of it, because if 1 is not careful, multithreading will make the state of objects chaotic.

In order to protect the atomicity, visibility and order of state, we programmers can say that we do our best. Among them, synchronized (synchronization) keyword is the simplest and most introductory solution.

If a class is immutable, so is the state of an object. In this way, every time the state of an object is changed, a new object will be created for different threads to use, so we programmers don't have to worry about concurrency.

02. Common immutable classes

When it comes to immutable classes, the first thing that almost all programmers think of is String Class. Then why String Class should be designed to be immutable?

1) Need for constant pools

The string constant pool is Java 1 special storage area in heap memory, when creating 1 String Object, if this string does not exist in the constant pool, then 1 is created; If it already exists, it will not be created again, but directly reference the existing object. This can reduce the memory overhead of JVM and improve the efficiency.

2) Requirements for hashCode

Because the string is immutable, when it is created, its hashCode It is cached, so it is very suitable as a hash value (for example, as a key of HashMap), and only returns the same value for efficiency in multiple calls.

3) Thread safety

As mentioned earlier, if the state of an object is variable, it is easy to cause unexpected results in a multithreaded environment. String is immutable, so it can be shared among multiple threads without synchronization.

Therefore, when we call String Class, such as immutable 0 , substring() , toLowerCase()) A new object is always returned without affecting the previous value.


String cmower = " Silent King 2 , 1 An interesting programmer "; 
cmower.substring(0,4); 
System.out.println(cmower);//  Silent King 2 , 1 An interesting programmer  

Although the call substring() Method pair cmower Intercepted, but cmower Has not changed the value of.

Except for String Class, wrapper class Integer , Long And so on are also immutable classes.

03. Hand-rolling immutable class

It may be easy to understand an immutable class, but it may be a little difficult to create a custom immutable class. But going ahead despite difficulties is an indispensable quality for us as an excellent programmer. It is not easy for us to truly master it.

Next, please start with me and customize an immutable class. One is immutable, and the following four conditions must be met:

1) Ensure that the class is final Is not allowed to be inherited by other classes. 2) Ensure that all member variables (fields) are final In this way, they can only initialize values in the constructor and will not be modified later. 3) Do not provide any setter Method. 4) If you want to modify the state of the class, you must return 1 new object.

According to the above conditions, we customize a simple immutable class Writer .


public final class Writer { 
    private final String name; 
    private final int age; 
 
    public Writer(String name, int age) { 
        this.name = name; 
        this.age = age; 
    } 
 
    public int getAge() { 
        return age; 
    } 
 
    public String getName() { 
        return name; 
    } 
} 


Writer Class is final Of, name And age Also final Yes, no setter Method.

OK, it is said that this author has shared many blogs and is widely loved by readers, so a certain publishing house asked him to write a book (Book). The Book class is defined as follows:


public class Book { 
    private String name; 
    private int price; 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 
    public int getPrice() { 
        return price; 
    } 
 
    public void setPrice(int price) { 
        this.price = price; 
    } 
 
    @Override 
    public String toString() { 
        return "Book{" + 
                "name='" + name + '\'' + 
                ", price=" + price + 
                '}'; 
    } 
} 


Two fields, which are name And setter 0 , and setter 1 And setter 2 The rewritten toString() Method. Then, in Writer Append 1 mutable object field to the class book .


public final class Writer { 
    private final String name; 
    private final int age; 
    private final Book book; 
 
    public Writer(String name, int age, Book book) { 
        this.name = name; 
        this.age = age; 
        this.book = book; 
    } 
 
    public int getAge() { 
        return age; 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public Book getBook() { 
        return book; 
    } 
} 


And appended to the constructor Book Parameter, and Book Adj. setter 1 Method.

With the above done, let's create a new test class to see if the state of the Writer class is really immutable.


public class WriterDemo { 
    public static void main(String[] args) { 
        Book book = new Book(); 
        book.setName("Web Advanced road of full stack development "); 
        book.setPrice(79); 
 
        Writer writer = new Writer(" Silent King 2",18, book); 
        System.out.println(" Pricing: " + writer.getBook()); 
        writer.getBook().setPrice(59); 
        System.out.println(" Promotional price: " + writer.getBook()); 
    } 
} 

The output of the program is as follows:

Pricing: Book {name= 'Web Advanced Road to Full Stack Development', price=79}
Promotional price: Book {name= 'Web Advanced Road to Full Stack Development', price=59}

Unfortunately, the immutability of Writer class has been destroyed and the price has changed. To solve this problem, we need to add one content to the definition rule of immutable classes:

If an immutable class contains objects of a mutable class, you need to ensure that a copy of the mutable object is returned. That is to say, Writer Class in the getBook() Method should be modified to:


public Book getBook() { 
    Book clone = new Book(); 
    clone.setPrice(this.book.getPrice()); 
    clone.setName(this.book.getName()); 
    return clone; 
} 

In this case, after the constructor is initialized, the Book The object will not be modified again. At this point, run WriterDemo You will find that the price is no longer changing.

Pricing: Book {name= 'Web Advanced Road to Full Stack Development', price=79}
Promotional price: Book {name= 'Web Advanced Road to Full Stack Development', price=79}

04. Summary

Immutable classes have many advantages, as mentioned earlier String Class, especially in a multithreaded environment, it is very safe. Although each modification will create a new object, which increases the memory consumption, this shortcoming is obviously insignificant compared with its advantages-nothing more than picking up watermelons and losing sesame seeds.


Related articles: