Java Mutable and Immutable concepts - java

Can we create an Immutable object, that contains a mutable object? Is is possible?
please make me more clear about this.
Thanks in advance.

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.
There's no setter methods. Nor any methods that modifies value.
We can create a string from a char array, but the char array is copied inside the constructor, so modifying the original array would have no effect to the newly created string.
The value field could also be shared by multiple String instances, but as long as it's not leaked, it's safe.
We can convert a string back to a char array, but again, its a copy.
So the answer is yes, if we follow a design strategy carefully.

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

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.

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.

I think that it's possible. But access modifier of variable which refers to mutable object must be final.

Related

What are Value Types from Project Valhalla?

I've started reading about Project Valhalla and there is something I really don't understand and it's the Value Types.
This is what I understand:
1) Are objects that can't be compare it as reference?
final ValueType a = new ValueType();
final ValueType b = a;
System.out.println(a==b); returns false????
In Google AutoValue code example, it states
if(o == this){return true;}//equals method implementation what is this? I am comparing references here right?
2) According to Wikipedia, highly-efficient small 'objects' without inheritance. What do Small Objects? and Without inheritance mean?
Is this not possible using VT?
public final class ValueType extends Any //is this not possible??
3) Why are they used? Which scenario would be used and how would it be used.
4) According to Google AutoValue Library, in a nutshell, a value-typed object is an object without an identity, i.e. two value objects are considered equal if their respective internal state is equal. My question is: do they have state and should they implement equals and hashcode. What does object without an identity mean?
5) Is this assertion correct?
public static void main(final String[] args)
{
final Test clazz = new Test();
final AutoValue value = new AutoValue("Java Belongs to SUN");//Constructor Name
clazz.mutate(value);
System.out.println(value.getName()); //would print: Java Belongs to SUN??
}
private void mutate(final AutoValue value){value.setName("Java now is part of Oracle Corporation");return;}
If it is so, would JVM gain memory not tracking this Objects or Values between methods calls?
Project Valhalla is part of initial Project of Java 10 would be ready in 2018 or so.
Your final assertion is correct. The ValueType variables are entirely copied when passing them as a parameter to a function, rather than typically just getting a copy of the reference to an object. This allows you to treat a small object as if it were a value type like int or boolean.
1) Under Project Valhalla, two ValueTypes would be compared by fields directly, even for == checks, much like primitive types. With Google's AutoValue types, you would never use == directly, because that would still be an identity check.
2) Small Objects means that this should be used for objects that only have a few fields, as the whole content of the object is going to be copied repeatedly. Large objects would be better served with passes by reference.
Without Inheritance means that you won't be able to use polymorphism for Value Type objects. Because Value Types are meant to be stored directly, like primitive values, they don't include any class information, so the JVM must always be able to infer what the object is from the program itself, instead of from any information on the object. For example, an Integer field could be a Value Type member, while a Number field would have to still be by reference.
3) They are used to avoid the dereference penalty normally required for accessing an object's members. For example, with a List of Points, each Point is actually a reference to the x and y values in memory, so iterating over the list will involve many dereferences. If the Points were stored directly in the list, this would be avoided.
4) Object Without an Identity means that all that matters about the object is its value. Just as an int valued 1 should be the same as all other ints valued 1, and all Strings "hello world" are equal to all other Strings "hello world", whether or not they are actually the same object. By contrast, two ArrayLists that are both empty, while at the time equal, have identity, because they are mutable, and adding an element to one list must be distinct from adding an element to the other list.
5) Under Project Valhalla, the AutoValue, if it is a Value Object, would be immutable, so there would be no setName method to call. It would be similar to how you can never mutate 1 into 2, you instead modify where a 1 is located so that a 2 is there instead.
Source: http://cr.openjdk.java.net/~jrose/values/values-0.html
The other answers are fine, but there is one other perspective about the core point of value objects: they give you stack semantics.
Meaning: before project Valhalla, you either have primitive "objects" and
reference objects. The first ones can exist on the stack, but real objects only live on the heap.
Value objects will change that. You can have "real" objects - but their data only resides on the stack. This means that you do not have a reference (and therefore cost for de-referencing) anything - just like primitive types, the value is directly placed on the stack. But now that value can be more than just a single int, long, ... - you can have a real, "complex" object - but all its data is directly there on the stack.
And because of that, you can nicely do a == b now - because now you are no longer comparing references that point to the heap - but a and b directly have their corresponding values.
UPDATE 2019/2020, Build 14-valhalla+4-55 (2019/8/30)
Inline Class is the new name of "Value Type". According to current project state Inline Classes don't support inheritance but are able to extend interfaces. Following statement is legal:
public inline class MyInlineClass extends SomeJavaInterface {}
They do have equals, hashcode (and toString) methods. "==" operation and equals (default implementation) are same for simple case, where only Inline Classes and primitive fields are involved. But it is not true in general.
It becomes messy, if you add a classic Java Object (including String and Array) as a field inside of Inline Class. In this case "==" operation most probably won't work as expected anymore and you have to fallback to classic custom equal implementation.
Inline objects are immutable and don't support clone (clone makes no sense).
A possible usecase for Inline Classes would be complex numbers or matrix algebra, which is essential for neural networks algorithms of artificial intelligence systems.

"There is no deep copy in java," but does it matter for list of Strings?

Let's say I do:
public List<E> gimmeAList(List<E> original) {
return new ArrayList<E>(original); // this is a shallow memcopy.
}
I try to modify the new list, but since Strings (or any immutable object) are immutable, doing something like: gimmeAList(something).get(0).replace("a", "b"); doesn't ACTUALLY seem to change anything in either lists.
So in this case, am I allowed to just assume (for immutable objects in a list) that new ArrayList<E>(original) is guaranteed to be, for all intents and purposes, basically a deep copy?
Yes, absolutely - copying a collection of immutable objects is effectively deep, unless you do something crazy like synchronizing on the references or comparing them for reference equality (i.e. operations which depend on object identity).
Copies of immutable objects are practically (or effectively) deep. However, it matters if the type E is mutable. But if it were so, you could call clone() on each Cloneable E and then you have a "deep copy". I believe your original premise "there is no deep copy in java" is incorrect, assuming you meant there is no way to create a "deep copy".
Object references in Java may be used to encapsulate identity, mutable state, both, or neither, in addition to encapsulating immutable aspects of state other than identity. Making a proper copy of an object which contains references to other objects requires knowing what is encapsulated by those references. Assuming foo is an object with reference-type field bar, and fooCopy is supposed to be a copy of foo...
If foo.bar is used to encapsulate the identity of an object, but not mutable state, then fooCopy.bar should identify the same object.
If foo.bar is used to encapsulate an object's mutable state, but not its identity, then fooCopy.bar should identify a newly-constructed copy of the object identified by foo.bar.
If foo.bar is used to encapsulate both identity and mutable state, then it will generally not be possible to make a proper copy of foo in isolation. If foo is part of a large forest of interconnected objects, it may be possible to construct a new forest of objects whose interconnections are isomorphic to those of the original, and have fooCopy.bar identify the object within that forest that corresponds to foo.bar's place in the original, but that's not apt to be simple.
If foo.bar encapsulates neither identity nor mutable state, then fooCopy.bar may legitimately identify either the same object as foo.bar, or a legitimate copy of the object identified by foo.bar.
Since string references are generally used to encapsulate neither identity nor mutable state, the last scenario applies; one may either copy the string reference or store a reference to a new copy the underlying string, whichever is more convenient.

Construct a new Object() with the toString result of another Object

I was wondering if it was possible to get some String value of an Object to access that Object on the same machine (same RAM) or the same VM via that particular String.
e.g.
Object objA1 = new Object();
System.out.print(objA1.adress); => output: d146a6581ed9e
Object objExt = Object.buildFromMemoryAdress("d146a6581ed9e");
I hope you understand what I'm trying to understand.
EDIT: I found in
http://javapapers.com/core-java/address-of-a-java-object/#&slider1=1
a Class that allows me to get the String of the logical address of an instance on the (VM?) memory: sun.misc.Unsafe
I think I can also use Unsafe to retrieve an Object from the (restricted to the VM?) memory.
If not possible like this, how would I do it, and since it's out of curiosity are there any other languages (especially high end) that allow direct memory access like this?
It is incorrect to assume that the number that you see in the toString() result is the memory address.
It is, in fact, the object's hash code. If the object isn't modified, its hash code remains constant. However, its memory address can change at any time: a compacting garbage collector can decide to move the object in memory whenever it feels like it.
Absolutely not. In fact, it's clearly impossible, given that you can obviously have two different objects whose toString() methods return the same string. As a simple example:
Integer a = new Integer(10);
Integer b = new Integer(10);
Object x = Object.buildFromToString("10");
What should x refer to? The same object that a refers to, or the same object that b refers to?
toString() is not meant to return an object identifier - it's just meant to return some sort of textual representation of an object. Just because the default implementation returns something which looks a bit like an identifier shouldn't be taken as an indication that it should be used as an identifier.
If you want to store some way of accessing an object at some other point in time, I suggest you just store a reference to it as an Object variable.
No, this is not possible. Java objects are only accessible if you have a reference to those objects. What you can do is store your objects in a Map<String, Object> under a given name, and get back the reference of the object from its name, using the map.

Deep copy, shallow copy, clone

I need clarification on the differences between deep copy, shallow copy, and clone in Java
Unfortunately, "shallow copy", "deep copy" and "clone" are all rather ill-defined terms.
In the Java context, we first need to make a distinction between "copying a value" and "copying an object".
int a = 1;
int b = a; // copying a value
int[] s = new int[]{42};
int[] t = s; // copying a value (the object reference for the array above)
StringBuffer sb = new StringBuffer("Hi mom");
// copying an object.
StringBuffer sb2 = new StringBuffer(sb);
In short, an assignment of a reference to a variable whose type is a reference type is "copying a value" where the value is the object reference. To copy an object, something needs to use new, either explicitly or under the hood.
Now for "shallow" versus "deep" copying of objects. Shallow copying generally means copying only one level of an object, while deep copying generally means copying more than one level. The problem is in deciding what we mean by a level. Consider this:
public class Example {
public int foo;
public int[] bar;
public Example() { };
public Example(int foo, int[] bar) { this.foo = foo; this.bar = bar; };
}
Example eg1 = new Example(1, new int[]{1, 2});
Example eg2 = ...
The normal interpretation is that a "shallow" copy of eg1 would be a new Example object whose foo equals 1 and whose bar field refers to the same array as in the original; e.g.
Example eg2 = new Example(eg1.foo, eg1.bar);
The normal interpretation of a "deep" copy of eg1 would be a new Example object whose foo equals 1 and whose bar field refers to a copy of the original array; e.g.
Example eg2 = new Example(eg1.foo, Arrays.copy(eg1.bar));
(People coming from a C / C++ background might say that a reference assignment produces a shallow copy. However, that's not what we normally mean by shallow copying in the Java context ...)
Two more questions / areas of uncertainty exist:
How deep is deep? Does it stop at two levels? Three levels? Does it mean the whole graph of connected objects?
What about encapsulated data types; e.g. a String? A String is actually not just one object. In fact, it is an "object" with some scalar fields, and a reference to an array of characters. However, the array of characters is completely hidden by the API. So, when we talk about copying a String, does it make sense to call it a "shallow" copy or a "deep" copy? Or should we just call it a copy?
Finally, clone. Clone is a method that exists on all classes (and arrays) that is generally thought to produce a copy of the target object. However:
The specification of this method deliberately does not say whether this is a shallow or deep copy (assuming that is a meaningful distinction).
In fact, the specification does not even specifically state that clone produces a new object.
Here's what the javadoc says:
"Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression x.clone() != x will be true, and that the expression x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements. While it is typically the case that x.clone().equals(x) will be true, this is not an absolute requirement."
Note, that this is saying that at one extreme the clone might be the target object, and at the other extreme the clone might not equal the original. And this assumes that clone is even supported.
In short, clone potentially means something different for every Java class.
Some people argue (as #supercat does in comments) that the Java clone() method is broken. But I think the correct conclusion is that the concept of clone is broken in the context of OO. AFAIK, it is impossible to develop a unified model of cloning that is consistent and usable across all object types.
The term "clone" is ambiguous (though the Java class library includes a Cloneable interface) and can refer to a deep copy or a shallow copy. Deep/shallow copies are not specifically tied to Java but are a general concept relating to making a copy of an object, and refers to how members of an object are also copied.
As an example, let's say you have a person class:
class Person {
String name;
List<String> emailAddresses
}
How do you clone objects of this class? If you are performing a shallow copy, you might copy name and put a reference to emailAddresses in the new object. But if you modified the contents of the emailAddresses list, you would be modifying the list in both copies (since that's how object references work).
A deep copy would mean that you recursively copy every member, so you would need to create a new List for the new Person, and then copy the contents from the old to the new object.
Although the above example is trivial, the differences between deep and shallow copies are significant and have a major impact on any application, especially if you are trying to devise a generic clone method in advance, without knowing how someone might use it later. There are times when you need deep or shallow semantics, or some hybrid where you deep copy some members but not others.
Deep copy: Clone this object and every reference to every other object it has
Shallow copy: Clone this object and keep its references
Object clone() throws CloneNotSupportedException: It is not specified whether this should return a deep or shallow copy, but at the very least: o.clone() != o
The terms "shallow copy" and "deep copy" are a bit vague; I would suggest using the terms "memberwise clone" and what I would call a "semantic clone". A "memberwise clone" of an object is a new object, of the same run-time type as the original, for every field, the system effectively performs "newObject.field = oldObject.field". The base Object.Clone() performs a memberwise clone; memberwise cloning is generally the right starting point for cloning an object, but in most cases some "fixup work" will be required following a memberwise clone. In many cases attempting to use an object produced via memberwise clone without first performing the necessary fixup will cause bad things to happen, including the corruption of the object that was cloned and possibly other objects as well. Some people use the term "shallow cloning" to refer to memberwise cloning, but that's not the only use of the term.
A "semantic clone" is an object which is contains the same data as the original, from the point of view of the type. For examine, consider a BigList which contains an Array> and a count. A semantic-level clone of such an object would perform a memberwise clone, then replace the Array> with a new array, create new nested arrays, and copy all of the T's from the original arrays to the new ones. It would not attempt any sort of deep-cloning of the T's themselves. Ironically, some people refer to the of cloning "shallow cloning", while others call it "deep cloning". Not exactly useful terminology.
While there are cases where truly deep cloning (recursively copying all mutable types) is useful, it should only be performed by types whose constituents are designed for such an architecture. In many cases, truly deep cloning is excessive, and it may interfere with situations where what's needed is in fact an object whose visible contents refer to the same objects as another (i.e. a semantic-level copy). In cases where the visible contents of an object are recursively derived from other objects, a semantic-level clone would imply a recursive deep clone, but in cases where the visible contents are just some generic type, code shouldn't blindly deep-clone everything that looks like it might possibly be deep-clone-able.

Can I set the value of a String in Java without using a constructor?

How-Do/Can I set the value of a String object in Java (without creating a new String object)?
There are no "set" methods on String. Strings are immutable in Java. To change the value of a String variable you need to assign a different string to the variable. You can't change the existing string.
(without creating a new String object)
Assigning doesn't create a new object - it copies the reference. Note that even if you write something like this:
s = "hello";
it won't create a new string object each time it is run. The string object will come from the string pool.
Actually there is no way to do that in Java, the String objects are immutable by default.
In fact, that's one of the reason why using the "+" concatenation operator like "str1" + "str2" is terribly inefficient, because what it does is copy every string in order to produce a third one.
Depending on your need you should consider using StringBuilder
Strings are immutable so you cannot change the value of an already created string.
The String object is immutable in Java so any changes create a new String object. Use a StringBuilder if you want to make changes to a string like object without creating new objects. As a bonus the StringBuilder allows you to preallocate additional memory if you know something about the eventual length of your string.
I stumbled across this question because i have to set a string within an "enclosing type" - an anonymous type. But all variables i want to set inside and use outside must be final.
The simple solution is to use StringBuilder - it's an mutable String.
It depends a bit on your definition of object. If you mean the reference, no. A reference is always created. If you mean the memory used by the characters, sure.
Strings are interned (if possible) which means that in an assignment:
String s1 = "Hello";
String s2 = "Hello";
there are 2 references (pointers to a memory location), but Hello is in memory on only 1 place. This is one of the reasons Strings can't be modified.
Sure you can access the internal char array via reflection. But it's usually a bad idea to do so. More on http://www.eclipsezone.com/eclipse/forums/t16714.html.

Categories

Resources