What is an immutable object? Immutable objects mean that after an object is created, it cannot change its state, and the object is immutable. The inability to change the state means that the member variable within the object cannot be changed, that the value of the underlying data type cannot be changed, that a variable of the reference type cannot point to another object, and that the state of the object to which the reference type points cannot be changed.
Here is a break between the object and the object's reference, the object is placed in the stack, and the object is placed in the heap, see this example, the String s = "123" ; s = "456"
surface S is changed, but to make it clear that the change is only a String object reference S, and "123" This object is not changed. Look at a diagram:
We all say that string is an immutable object, so let's analyze the source of string to see how it guarantees that the string object is immutable.
Public Final classStringImplementsJava.io.Serializable, comparable<string>, charsequence {/**The value is used for character storage.*/ Private Final Charvalue[]; /**Cache The hash code for the string*/ Private intHash//Default to 0 Publicstring (string original) { This. Value =Original.value; This. hash =Original.hash; } Publicstring concat (String str) {intOtherlen =str.length (); if(Otherlen = = 0) { return This; } intLen =value.length; CharBuf[] = arrays.copyof (value, Len +Otherlen); Str.getchars (buf, Len); return NewString (BUF,true); } Public Booleanequals (Object anobject) {if( This==anobject) { return true; } if(AnObjectinstanceofString) {String anotherstring=(String) AnObject; intn =value.length; if(n = =anotherString.value.length) {CharV1[] =value; CharV2[] =Anotherstring.value; inti = 0; while(n--! = 0) { if(V1[i]! =V2[i])return false; I++; } return true; } } return false; } ...
By analyzing the source, we know that the first string class and the char array that holds the string are final types, which guarantees that the string class cannot be inherited, and that the reference itself does not change, but that does not mean that the property is immutable because we can change the Val The specific value in the UE array to change the purpose of value.
public static void main (string[] args) { char [] value = {' A ', ' B ', ' C ', ' d ' }; System.out.println (value); for (int i = 0; i < value.length; i+ + if (i = = 1; }} System.out.println (value); // ABCD }
But further research will find that the property of value is defined as private, and the String does not provide a corresponding get set method, so we cannot manipulate it. And those that we often think changed the String object, such as SubString concat touppercase tirm Read the source, found that these methods are re-created a char array, and did not change the previous object. This is why we often say that String is an immutable object. But we can still change the value by reflection, and look at an example, but we don't usually do that.
Public Static voidMain (string[] args)throwsException {//Create the string "Hello world" and assign it to the reference sString s = "Hello World"; System.out.println ("s =" + s);//Hello World//Get the Value field in the String classField valuefieldofstring = String.class. Getdeclaredfield ("value"); //changing the access rights of the Value propertyValuefieldofstring.setaccessible (true); //gets the value of the Value property on the S object Char[] Value = (Char[]) valuefieldofstring.get (s); //Change the 5th character in the array referenced by valueValue[5] = ' _ '; System.out.println ("s =" + s);//Hello_world}
Why would you want to design a String as an immutable object? For efficiency and safety, of course, it is also due to the ultra-high frequency of the String. Efficiency is mainly reflected in when we copy the string object, I just need to copy the reference, do not need to copy the specific object, and in a multithreaded environment, if different threads simultaneously modify the string object, there is no effect on each other. Because a new string will be created once the change is made, which guarantees the thread's security.
In addition, there is a string constant pool in the heap, we create the string will exist here, when creating the same string, it is actually pointing to the same place. This saves a lot of space, and of course, the ability to string constant pools is also because string is an immutable object.
Because the String is immutable, the value of Hashcode is computed when the object is created and cached in the field hash. This makes the String in the Map suitable as the primary key, fast. (Because the hash value of the primary key is calculated when we locate in the hash table.) )
/*** /privateint// Default to 0
There is also a database connection when we pass a string to the user name, password, connected library and other information, if the string is variable, it is likely to be tampered with by hackers.
PS. The wrapper classes for the basic types are immutable objects, so the reason for the design is because they are used too often, and the benefits are already mentioned above. Suddenly I learned a lot of details that I hadn't noticed before.
The source version is JDK 1.7
Recommended reading: Www.cnblogs.com/YJK923/p/9479805.html
Reference: zhuanlan.zhihu.com/p/38144507