I would like to feel the 'magic power' of the copyOf()
method of Guava guava-libraries
.
There is small app that I use to check it.
Here is the documentation:
The JDK provides
Collections.unmodifiableXXX
methods, but in our opinion, these can be
- unwieldy and verbose; unpleasant to use everywhere you want to make defensive copies
- unsafe: the returned collections are only truly immutable if nobody holds a reference to the original collection
So, I try to build a model where "someone holds a reference to the original collection"
. Thus, working with a copy of collection I should not be worried about changing value on copy. But magic does not work so far (there are two tries: 1. copyOf(collection)
, 2. copyOf(iterator)
):
import com.google.common.collect.ImmutableList;
import java.util.LinkedList;
import java.util.List;
class MyObject {
String name;
public MyObject(String name) {this.name = name;}
@Override
public String toString() {
return name;
}
}
public class ListUnsafe {
List<MyObject> list = new LinkedList<MyObject>();
{
list.add(new MyObject("a"));
list.add(new MyObject("b"));
list.add(new MyObject("c"));
}
public List<MyObject> getList() {
return ImmutableList.copyOf(list);
}
public List<MyObject> getCopyIterator() {
return ImmutableList.copyOf(list.iterator());
}
public static void main(String[] args) {
ListUnsafe obj = new ListUnsafe();
{
MyObject ref = obj.list.get(0);
List<MyObject> myList = obj.getList();
MyObject copyObj = myList.get(0);
copyObj.name = "new";
System.out.println("ref: " + ref);
}
obj = new ListUnsafe();
{
MyObject ref = obj.list.get(0);
List<MyObject> myList = obj.getCopyIterator();
MyObject copyObj = myList.iterator().next();
copyObj.name = "new";
System.out.println("ref: " + ref);
}
}
}
The output:
ref: new
ref: new
It means that we changed original data. What we did not want.
Question
Why it does not do copy?
How it differs from unmodifiableXXX
?
There is link to similar question:
The answer says about copyOf
:
- (from source)
copyOf(Collection)
instance doesn't create temporaryArrayList
(copyOf(Iterable)
andcopyOf(Iterator)
do so).