What is difference between mutable and immutable S

2019-01-16 10:14发布

As per my knowledge,

a mutable string can be changed, and an immutable string cannot be changed.

Here I want to change the value of String like this,

String str="Good";
str=str+" Morning";

and other way is,

StringBuffer str= new StringBuffer("Good");
str.append(" Morning");

In both the cases I am trying to alter the value of str. Can anyone tell me, what is difference in both case and give me clear picture of mutable and immutable objects.

12条回答
聊天终结者
2楼-- · 2019-01-16 10:25

In Java, all strings are immutable. When you are trying to modify a String, what you are really doing is creating a new one. However, when you use a StringBuilder, you are actually modifying the contents, instead of creating a new one.

查看更多
Bombasti
3楼-- · 2019-01-16 10:28

Mutable Objects: When you have a reference to an instance of an object, the contents of that instance can be altered

Immutable Objects: When you have a reference to an instance of an object, the contents of that instance cannot be altered

Let's understand this with an example :

String myString = new String( "old String" );
System.out.println( myString );
myString = new String( "new String" );
System.out.println( myString );

The output from this is:

old String
new String

Now we find that the value displayed by the myString variable has changed. We have defined immutable objects as being unable to change in value, so what is happening? Let's extend the example again to watch the myString variable closer.

String myString = new String( "old String" );
String myCache = myString;
System.out.println( "equal: " + myString.equals( myCache ) );
System.out.println( "same:  " + ( myString == myCache ) );
myString = "not " + myString;
System.out.println( "equal: " + myString.equals( myCache ) );
System.out.println( "same:  " + ( myString == myCache ) );

The result from executing this is:

equal: true
same:  true
equal: false
same:  false

What this shows is that variable myString is referencing a new instance of the String class. The contents of the object didn't change; we discarded the instance and changed our reference to a new one with new contents.

查看更多
小情绪 Triste *
4楼-- · 2019-01-16 10:31

Mutable means you will save the same reference to variable and change its contents but immutable you can not change contents but you will declare new reference contains the new and the old value of the variable

Ex Immutable -> String

String x = "value0ne";// adresse one x += "valueTwo"; //an other adresse {adresse two} adresse on the heap memory change.

Mutable -> StringBuffer - StringBuilder StringBuilder sb = new StringBuilder(); sb.append("valueOne"); // adresse One sb.append("valueTwo"); // adresse One

sb still in the same adresse i hope this comment helps

查看更多
干净又极端
5楼-- · 2019-01-16 10:32

Case 1:

String str = "Good";
str = str + " Morning";

In the above code you create 3 String Objects.

  1. "Good" it goes into the String Pool.
  2. " Morning" it goes into the String Pool as well.
  3. "Good Morning" created by concatenating "Good" and " Morning". This guy goes on the Heap.

Note: Strings are always immutable. There is no, such thing as a mutable String. str is just a reference which eventually points to "Good Morning". You are actually, not working on 1 object. you have 3 distinct String Objects.


Case 2:

StringBuffer str = new StringBuffer("Good"); 
str.append(" Morning");

StringBuffer contains an array of characters. It is not same as a String. The above code adds characters to the existing array. Effectively, StringBuffer is mutable, its String representation isn't.

查看更多
混吃等死
6楼-- · 2019-01-16 10:33

Java Strings are immutable.

In your first example, you are changing the reference to the String, thus assigning it the value of two other Strings combined: str + " Morning".

On the contrary, a StringBuilder or StringBuffer can be modified through its methods.

查看更多
等我变得足够好
7楼-- · 2019-01-16 10:35

String in Java is immutable. However what does it mean to be mutable in programming context is the first question. Consider following class,

public class Dimension {
    private int height;

    private int width;

    public Dimenstion() {
    }

    public void setSize(int height, int width) {
        this.height = height;
        this.width = width;
    }

    public getHeight() {
        return height;
    }

    public getWidth() {
        return width;
    }
}

Now after creating the instance of Dimension we can always update it's attributes. Note that if any of the attribute, in other sense state, can be updated for instance of the class then it is said to be mutable. We can always do following,

Dimension d = new Dimension();
d.setSize(10, 20);// Dimension changed
d.setSize(10, 200);// Dimension changed
d.setSize(100, 200);// Dimension changed

Let's see in different ways we can create a String in Java.

String str1 = "Hey!";
String str2 = "Jack";
String str3 = new String("Hey Jack!");
String str4 = new String(new char[] {'H', 'e', 'y', '!'});
String str5 = str1 + str2;
str1 = "Hi !";
// ...

So,

  1. str1 and str2 are String literals which gets created in String constant pool
  2. str3, str4 and str5 are String Objects which are placed in Heap memory
  3. str1 = "Hi!"; creates "Hi!" in String constant pool and it's totally different reference than "Hey!" which str1 referencing earlier.

Here we are creating the String literal or String Object. Both are different, I would suggest you to read following post to understand more about it.

In any String declaration, one thing is common, that it does not modify but it gets created or shifted to other.

String str = "Good"; // Create the String literal in String pool
str = str + " Morning"; // Create String with concatenation of str + "Morning"
|_____________________|
       |- Step 1 : Concatenate "Good"  and " Morning" with StringBuilder
       |- Step 2 : assign reference of created "Good Morning" String Object to str

How String became immutable ?

It's non changing behaviour, means, the value once assigned can not be updated in any other way. String class internally holds data in character array. Moreover, class is created to be immutable. Take a look at this strategy for defining immutable class.

Shifting the reference does not mean you changed it's value. It would be mutable if you can update the character array which is behind the scene in String class. But in reality that array will be initialized once and throughout the program it remains the same.

Why StringBuffer is mutable ?

As you already guessed, StringBuffer class is mutable itself as you can update it's state directly. Similar to String it also holds value in character array and you can manipulate that array by different methods i.e. append, delete, insert etc. which directly changes the character value array.

查看更多
登录 后发表回答