Reputation: 108
Can we create an Immutable object, that contains a mutable object? Is is possible? please make me more clear about this.
Thanks in advance.
Upvotes: 0
Views: 987
Reputation: 12181
Edit: This depends somewhat on what you mean by "immutable." As another person pointed out, sometimes "immutable" is defined as a form of "shallow" immutability - i.e. constant references to mutable objects are allowed. I'm not fond of this definition myself. Some people might disagree with me here (and hopefully no one will downvote b/c of a difference of opinion), I think it's much clearer to define "immutability" as "having no mutable state of any kind."
Under this definition, the answer to your question is **no* because if it refers to mutable objects that gives it mutable state, which would make the object itself mutable.
I think it's important at this point to distinguish between a constant reference or pointer and an immutable object. For example, the following code is a constant reference to a constant object:
private final string abc = "John";
Note that you can't modify the state of "abc" (i.e. that particular string will always be "John" - you can't change it to "Johnny" later, you'd need to create a new string. Also, you can't replace "John" with a new string (i.e. the variable "abc" itself will always refer to that string).
The following code is a mutable reference to an immutable object:
public string abc = "John";
(By the way, I do realize you should use a property here instead).
If you were to later do:
abc = "Johnny";
you'd be allowed to do that. In this case, you're changing the object that the variable "abc" is referring to, not the original string. The string "John" will always have that value as long as it exists.
However, consider the following object:
public class Defg
{
public int Count;
public Defg(int Count)
{
this.Count = Count;
}
}
Clearly, this is a mutable class (because you can change the value of "Count").
You can do the following:
// Mutable reference to a mutable object. Note: "Count: 1" is a bit of C# syntax that just means that the "Count" parameter is set to 1. It's not strictly necessary here, I just added it for clarity.
public Defg Mutable = new Defg(Count: 1);
// Constant reference to a mutable object
public final Defg ConstReference = new Defg(Count: 1);
Note that the following is all perfectly valid:
Mutable = new Defg(Count: 10);
Mutable.Count = 4;
ConstReference.Count = 3;
However, you cannot do the following:
ConstReference = new Defg(Count: 3);
Note, in particular, that Defg can't possibly be an immutable object because you can change its state.
To summarize:
a) It's perfectly possible to have either a mutable reference to a constant object or a constant reference to a mutable object - the mutability of the reference to the object has nothing to do with whether the object itself is mutable and vice versa.
b) Whether an object that refers to mutable objects can still be considered immutable depends on your definition of "immutable." In my opinion it can't because referring to a mutable object gives it mutable state; it would be confusing/misleading at best to describe that as immutable.
Upvotes: 0
Reputation: 18148
In Java (and as far as I know all other mainstream languages with a const
/ final
/ readyonly
/ val
etc keyword) an "immutable" object can contain references to mutable objects. For a deeper dive into immutability see this paper - the quick takeaway is that there are unofficial Java extensions that allow you to specify that e.g. an immutable object can only contain references to immutable objects, e.g. Javari or Joe3 or OIGJ
Upvotes: 1
Reputation: 8587
Yes we can.
Take for example the code from java.lang.String
:
/** The value is used for character storage. **/
private final char value[];
Obviously arrays are mutable because we can easily change their content like this:
value[0] = '&';
However String
is still immutable. That is, once created, its contents will never change. How does that happen?
Because even though value
is mutable, there's no "regular" way for the user of String
to modify it:
value
is declared private final
. And String
itself is final
, meaning no subclass.value
. value
field could also be shared by multiple String
instances, but as long as it's not leaked, it's safe.So the answer is yes, if we follow a design strategy carefully.
Upvotes: 3
Reputation: 1
I think that it's possible. But access modifier of variable which refers to mutable object must be final.
Upvotes: -1
Reputation: 27115
Objects in Java never really contain other objects--not like in C or in some other programming languages. Even the so-called "container" classes really just contain references to other objects.
An immutable object can refer to any other objects, mutable or immutable.
You can't change which other objects an immutable object refers to, but you can change the other objects if they are mutable.
Upvotes: 0