What is meant by immutable?

后端 未结 17 1608
天命终不由人
天命终不由人 2020-11-22 02:27

This could be the dumbest question ever asked but I think it is quite confusing for a Java newbie.

  1. Can somebody clarify what is meant by immutable? <
相关标签:
17条回答
  • 2020-11-22 03:08

    java.time

    It might be a bit late but in order to understand what an immutable object is, consider the following example from the new Java 8 Date and Time API (java.time). As you probably know all date objects from Java 8 are immutable so in the following example

    LocalDate date = LocalDate.of(2014, 3, 18); 
    date.plusYears(2);
    System.out.println(date);
    

    Output:

    2014-03-18

    This prints the same year as the initial date because the plusYears(2) returns a new object so the old date is still unchanged because it's an immutable object. Once created you cannot further modify it and the date variable still points to it.

    So, that code example should capture and use the new object instantiated and returned by that call to plusYears.

    LocalDate date = LocalDate.of(2014, 3, 18); 
    LocalDate dateAfterTwoYears = date.plusYears(2);
    

    date.toString()… 2014-03-18

    dateAfterTwoYears.toString()… 2016-03-18

    0 讨论(0)
  • 2020-11-22 03:08
    String s1="Hi";
    String s2=s1;
    s1="Bye";
    
    System.out.println(s2); //Hi  (if String was mutable output would be: Bye)
    System.out.println(s1); //Bye
    

    s1="Hi" : an object s1 was created with "Hi" value in it.

    s2=s1 : an object s2 is created with reference to s1 object.

    s1="Bye" : the previous s1 object's value doesn't change because s1 has String type and String type is an immutable type, instead compiler create a new String object with "Bye" value and s1 referenced to it. here when we print s2 value, the result will be "Hi" not "Bye" because s2 referenced to previous s1 object which had "Hi" value.

    0 讨论(0)
  • 2020-11-22 03:09

    Immutable means that once the constructor for an object has completed execution that instance can't be altered.

    This is useful as it means you can pass references to the object around, without worrying that someone else is going to change its contents. Especially when dealing with concurrency, there are no locking issues with objects that never change

    e.g.

    class Foo
    {
         private final String myvar;
    
         public Foo(final String initialValue)
         {
             this.myvar = initialValue;
         }
    
         public String getValue()
         {
             return this.myvar;
         }
    }
    

    Foo doesn't have to worry that the caller to getValue() might change the text in the string.

    If you imagine a similar class to Foo, but with a StringBuilder rather than a String as a member, you can see that a caller to getValue() would be able to alter the StringBuilder attribute of a Foo instance.

    Also beware of the different kinds of immutability you might find: Eric Lippert wrote a blog article about this. Basically you can have objects whose interface is immutable but behind the scenes actual mutables private state (and therefore can't be shared safely between threads).

    0 讨论(0)
  • 2020-11-22 03:15

    Immutable objects are objects that can't be changed programmatically. They're especially good for multi-threaded environments or other environments where more than one process is able to alter (mutate) the values in an object.

    Just to clarify, however, StringBuilder is actually a mutable object, not an immutable one. A regular java String is immutable (meaning that once it's been created you cannot change the underlying string without changing the object).

    For example, let's say that I have a class called ColoredString that has a String value and a String color:

    public class ColoredString {
    
        private String color;
        private String string;
    
        public ColoredString(String color, String string) {
            this.color  = color;
            this.string = string;
        }
    
        public String getColor()  { return this.color;  }
        public String getString() { return this.string; }
    
        public void setColor(String newColor) {
            this.color = newColor;
        }
    
    }
    

    In this example, the ColoredString is said to be mutable because you can change (mutate) one of its key properties without creating a new ColoredString class. The reason why this may be bad is, for example, let's say you have a GUI application which has multiple threads and you are using ColoredStrings to print data to the window. If you have an instance of ColoredString which was created as

    new ColoredString("Blue", "This is a blue string!");
    

    Then you would expect the string to always be "Blue". If another thread, however, got ahold of this instance and called

    blueString.setColor("Red");
    

    You would suddenly, and probably unexpectedly, now have a "Red" string when you wanted a "Blue" one. Because of this, immutable objects are almost always preferred when passing instances of objects around. When you have a case where mutable objects are really necessary, then you would typically guard the objet by only passing copies out from your specific field of control.

    To recap, in Java, java.lang.String is an immutable object (it cannot be changed once it's created) and java.lang.StringBuilder is a mutable object because it can be changed without creating a new instance.

    0 讨论(0)
  • 2020-11-22 03:15

    "immutable" means you cannot change value. If you have an instance of String class, any method you call which seems to modify the value, will actually create another String.

    String foo = "Hello";
    foo.substring(3);
    <-- foo here still has the same value "Hello"
    

    To preserve changes you should do something like this foo = foo.sustring(3);

    Immutable vs mutable can be funny when you work with collections. Think about what will happen if you use mutable object as a key for map and then change the value (tip: think about equals and hashCode).

    0 讨论(0)
  • 2020-11-22 03:15

    Once instanciated, cannot be altered. Consider a class that an instance of might be used as the key for a hashtable or similar. Check out Java best practices.

    0 讨论(0)
提交回复
热议问题