An immutable class is when an object instance of a class is created, and the properties of that instance cannot be changed. A common string is an immutable class. The property values of immutable types do not change, which is useful in multithreaded programming, without worrying about the object's property values being modified.
Let's take a look at how to implement an immutable type:
1. To ensure that the attribute value does not change, the attribute must be decorated with private and final.
2. To initialize the final property in the class's constructor, and to provide only getter methods, no setter methods are provided.
3. Override Equals and Hashcode, using the overridden Equals method to determine whether two objects are equal based on the attribute value, Hashcode method guarantees different objects, hashcode different.
The simplest way to implement an immutable class:
classperson{Privatefinal String FirstName; Privatefinal String LastName; PublicPerson (String firstname,string lastName) { This. firstname=FirstName; This. lastname=LastName; } PublicString Getfirstname () {returnFirstName; } PublicString Getlastname () {returnLastName; } @Override Publicboolean equals (Object obj) {if(obj instanceof person) {person P=(person) obj; return This. Firstname.equals (P.firstname) && This. Lastname.equals (P.lastname); }Else { Throw Newclasscastexception (); }} @Override Public inthashcode () {return( This. firstname+ This. LastName). Hashcode (); }}
The person class is an immutable class, properties are private and final, and only getter methods are provided, and the value of the property cannot be modified at all.
However, if a class contains a mutable type, it cannot be implemented so simply.
classname{PrivateString FirstName; PrivateString LastName; PublicName () {} PublicName (String firstName, String lastName) { This. Setfirstname (FirstName); This. Setlastname (LastName); } PublicString Getfirstname () {returnFirstName; } Public voidsetfirstname (String firstName) { This. FirstName =FirstName; } PublicString Getlastname () {returnLastName; } Public voidsetlastname (String lastName) { This. LastName =LastName; }}classperson{Privatefinal name name; PublicPerson (name name) { This. name=name; } PublicName GetName () {returnname; } @Override PublicString toString () {returnName.getfirstname () +"$"+Name.getlastname (); } }
The person class contains a mutable type name, although name is decorated with final and private and only getter, but the value of name can still be modified:
Person person= Thenew person (new Name ("Hello", "World")); SYSTEM.OUT.PRINTLN (person); Person.getname (). Setfirstname ("hel"); SYSTEM.OUT.PRINTLN (person);
Output Result:
Hello$worldhel$world
It is obviously not possible to achieve the purpose of immutable classes, in order to become immutable classes, you need to return a new object in the getter, in the constructor also with the new object initialization:
Public Person (name name) { this. name=new name (Name.getfirstname (), Name.getlastname ()); } Public Name getName () { returnnew Name (Name.getfirstname (), Name.getlastname ()); }
This will not change the value of the object instance at all. The string class uses a similar implementation, but uses a constant cache pool, which greatly improves performance. Each time the string object is initialized, the constant cache pool is checked first, and no new constant string is created in memory if it already exists.
An exploration of immutable types in Java