Getting a copy of an object - java

I don't fully understand when Java passes a copy/value and when it passes a "reference" (the pointer).
I'm trying to assign a copy of a static object I have, but I'm not sure how to go about it.
I have this:
static ArrayList<MyObject> myObjects;
I want to get a copy of myObjects so that I can play around with the values without affecting the original. Does it pass a reference or a copy/value when I use a getter like so:
public static ArrayList<MyObject> getMyObject()
{
return ThisClass.myObjects;
}
What does that return? If it's a reference, how can I get a copy?
I've seen these:
(How do I copy an object in Java?)
(Java: getter method vs. public instance variable: performance and memory)
(Is Java "pass-by-reference" or "pass-by-value"?)
(How can Java assignment be made to point to an object instead of making a copy?)
But I still don't quite understand what I'll get back.

Java will always return a reference and not a copy as long as it's not a primitive type (aka long,int,short,etc or one of the primitive wrappers Long,Integer, Short.
To get a copy you will need to either copy the data, use a copy constructor, or use the method clone which will create a new object with the appropriate values.
Example of a copy constructor with a list, by default this is a "shallow copy" meaning the objects inside are the same.
List<MyObject> myNewCopiedList = new ArrayList<MyObject>(oldList);
For a "deep copy", meaning the objects inside can be mutated without affecting the originals you will need to make a new List then add copies/clones of the object and add.
Example, assuming MyObject has a copy constructor or a clone method.
List<MyObject> myNewCopiedList = new ArrayList<MyObject>();
for (MyObject myo : oldList){
myNewCopiedList.add(new MyObject(myo)); // if there is a copy constructor
myNewCopiedList.add(myo.clone()); // if there is clone method
}

Think of it this way. Java is always pass by value.
For primitives, it is pass by value(actual value).
For objects, it is pass by value-of-reference.
public int square(int a) { //The parameter a is copy of actual int itself.
//So now there are 2 ints
a=a*a; //Only local copy a is actually modified.
//The integer variable passed(in caller function) is not modified.
return a;
}
If you call doSomething(d) where d is an object, a copy of reference pointing to this object is assigned to parameter a but there is only one object.
public void doSomething(Object a) {
// Here the parameter is a reference which points to an
// object, not the object itself
a.doMore(); //But doMore() does things using a different ref but on the same object.
//The object can be modified!
Object b = new Object();
a = b; //Object referenced by passed parameter does not change but
//copy of reference now points to different object.
// Now there is no reference of original object passed in this method.
}

Technically, Java is always pass-by-value. However, for a beginner's thinking, it's easier to think about it this way:
If it's a primitive type, it's pass-by-value.
If it's an object, it's pass-by-reference.
So in your example, you are returning a reference to the same static object in ThisClass. The reason I say this is technically pass-by-value is because your variable myObjects actually stores the memory address of the ArrayList<MyObject> which you declared, and it's this which is passed.

In order to properly make a copy of an object, one must know which non-primitive fields encapsulate
Mutable aspects of the object's state, but not its identity
The identity of an object and other immutable aspects, but no mutable aspects.
Aspects of the object which are expected never to be exposed to any code which might mutate them (and not identity)
Mutable aspects of the object's state, as well as its identity
Based upon what a field encapsulates, a correct copy of Foo
If one of Foo's field which encapsulates mutable state, a the corresponding field in a copy of Foo should hold a reference to a different object with the same state.
If a field encapsulates object identity, that field in the copy must hold a reference to the same object as in Foo--not a copy.
If a field encapsulates only immutable aspects other than identity, then a copy of Foo may either hold a reference to the same object as in Foo, or any object which has the same immutable state, as convenient.
If a field encapsulates both mutable state and identity, because the first two requirements will conflict, it will not be possible to copy the object in isolation.
In some cases, it may be possible to copy a set of mutable objects which use references to each other to encapsulate both state and identity. Such a copy must be performed on the set as a whole; for each object within the set, any field which in the original object encapsulates both the mutable state and identity of another object in the original set must in the copy refer to the corresponding object in the copied set.

Related

What's the deal with object array in java?

I know java is pass by value, period. However, I still can't figure out this.
public static void changeTheName(String obj){
obj.toUpperCase();
}
This method will not affect the original string object, Fairly understandable. Because strings are immutable and changing in string literals means that the reference variable will now refer to the new object and the old one will be left for the garbage collector. But when I pass a string array I'm able to change the string literals that means I'm able to change the references. Why is this happening with the array because if we do obj[]= new String[]{} it will not affect to the original array and the original still refers to the old array and that is similar to directly changing the string literals
public static void ChangeTheName(String obj[]){
for(int i=0;i<obj.length();i++) obj[i]=obj[i].toUpperCase;
}
Edit:
The answer I was looking for is that reference of obj and obj[0] are unique and that's why the second method is able to change the entire content of my array. As I'm from C background and I thought obj and obj[0] has same refernces but that is not the case in java for sure.
toUpperCase does not change the String, it returns a new String which is uppercase.
#karthikdivi said - toUpperCase() does not change the String. it returns a new String which is uppercase.
But as i understand that you want to know why object value is changed in method but not premitive data type value?
Although Java is strictly pass by value, the precise effect differs between whether a primitive type or a reference type is passed.
.
When we pass a primitive type to a method, it is passed by value. But when we pass an object to a method, the situation changes dramatically, because objects are passed by what is effectively call-by-reference. Java does this interesting thing that’s sort of a hybrid between pass-by-value and pass-by-reference. Basically, a parameter cannot be changed by the function, but the function can ask the parameter to change itself via calling some method within it.
While creating a variable of a class type, we only create a reference to an object. Thus, when we pass this reference to a method, the parameter that receives it will refer to the same object as that referred to by the argument.
This effectively means that objects act as if they are passed to methods by use of call-by-reference.
Changes to the object inside the method do reflect in the object used as an argument.
if you are doing like below will only change the value.
public static void(String obj[]){
for(String s:obj) {
s=s.toUpperCase();
}
}
I think thus make changes.

Java LinkedList.get() does not return deep copy? [duplicate]

This question already has answers here:
Java: recommended solution for deep cloning/copying an instance
(10 answers)
Closed 8 years ago.
I have a question about using a LinkedList and the .get() operation. Java as I understand passes objects by reference, so if I have a linked list called A, and I do temp B = A.get(i), I retrieve an object B that I can modify and the changes are reflected in A.get(i).
However, if the object B has within it (Say another LinkedList object), I do not get a deep copy correct? Is the solution that I must create a copy constructor for my class 'temp' in this example. Or is there a better, built-in way to do this?
Thanks for your help.
Java as I understand passes objects by reference..
No. Java pass everything by value. If you have a reference type, the reference is passed by value. See this question.
if I have a linked list called A, and I do temp B = A.get(i), I retrieve an object B that I can modify and the changes are reflected in A.get(i).
If you have a list of reference types get(i) will return a reference to a particular instance. The element in the list and your retrieved reference will refer to the same object. So if you change the object in some way, it will be "visible" from both references.
However, if the object B has within it (Say another LinkedList object), I do not get a deep copy correct?
Correct. You get a reference.
Is the solution that I must create a copy constructor for my class 'temp' in this example. Or is there a better, built-in way to do this?
If you need a deep copy of your object, you must implement it yourself.
Java as I understand passes objects by reference
No. It passes references by value. It doesn't pass objects at all [except in the case of RMI.]
so if I have a linked list called A, and I do temp B = A.get(i), I retrieve an object B
No. You retrieve a reference that refers to B. The same B whose reference you passed when you added it to the list.
that I can modify and the changes are reflected in A.get(i).
Yes, see above.
However, if the object B has within it (Say another LinkedList object), I do not get a deep copy correct?
Correct. Just like the first case. No difference whatsoever.
Is the solution that I must create a copy constructor for my class 'temp' in this example.
Solution to what? I've never used a copy constructor or the clone() method in Java since 1997. What problem are you trying to solve?
Or is there a better, built-in way to do this?
To do what?
It does not return a "deep copy" because there is no copying done at all, at least, not at the object level. Let me explain.
When you have an instance of an object, the variable that references that object is a pointer to the object. The object can be referenced and modified by many variables (pointers). Observe the following code:
// Let's assume I have a custom object class called Student
// Here the object is created and s now points to the new Student object
Student s = new Student();
// Here I create another variable that points to the same object
Student s2 = s;
Those two variables both point to the same object and any changes that one variable makes to the object will then be reflected in the other.
This ties into your list example. If you have a LinkedList of objects, it is actually a list of pointers to objects. So calling get(2) on the list will get a reference to the 3rd object in the list. The object that it's referencing is the object, not a copy. So any references, variables, methods etc. that were in this object will still be there.
I hope that answers your question :)

modify value in variable

I have a problem with one class in java
this class is public and extends of DefaultHandler
all method of this class are public too ... but the variables are private...
My problem is that if I copy the value in other variable and modify this second variable the first change too.
is like static variables.. but they are no static... any idea!!!
thanks in advance
This is because you are actually modifying the same object. For instance, if you have
Object obj = new Object();
Object obj2 = obj;
You don't actually copy anything, you simply make obj2 "point" (not quite the right term, but it will work for now) to obj. Any changes to obj2 will be reflected in obj. Therefore, if you want to actually copy it, you need to physically create a new Object and then manually copy all of the values into the new creation. You could implement the prototype pattern to copy the object. Primitives don't behave this way so if you were to do the same thing with a double or an int for instance, it would behave the way you expect.
Does all of that make sense?
You are probably having a problem with passing by reference versus passing by value. This page explains what I mean http://www.cs.umd.edu/class/sum2004/cmsc420/sum4v3e01/node6.html.
You probably are copying a reference to a changeable object, not the object itself; so after the copy, you have two references to the same object. Changing that object through either reference will have the same effect.
I can't tell you how to copy the actual object because there's no generic way to do it, but many classes provide a copy constructor or some other way to duplicate themselves. If you need help with that you'd have to provide more details.

How does Object class implement clone() method

In a book on Core Java, I found this excerpt :
Think about the way in which the
Object class can implement clone. It
knows nothing about the object at all,
so it can make only a field-by-field
copy. If all data fields in the object
are numbers or other basic types,
copying the fields is just fine. But
if the object contains references to
subobjects, then copying the field
gives you another reference to the
subobject, so the original and the
cloned objects still share some
information.
After reading this I was wondering, that How is the clone method originally implemented in Object Class?
What bothers me is that: how can a method in Object class make a field by field clone of a sub-class object, when it knows nothing about that class?
Actually, clone() is implemented in native code, so I assume it just does a memory copy (copy all the bytes) without knowing the contents.
Besides that, there is the Reflection API to gain knowlegde about a class (which would be slower, however).
Read this from the Javadoc:
protected Object clone() -
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. By
convention, the returned object should
be obtained by calling super.clone. If
a class and all of its superclasses
(except Object) obey this convention,
it will be the case that
x.clone().getClass() == x.getClass().
By convention, the object returned by
this method should be independent of
this object (which is being cloned).
To achieve this independence, it
may be necessary to modify one or more
fields of the object returned by
super.clone before returning it.
Typically, this means copying any
mutable objects that comprise the
internal "deep structure" of the
object being cloned and replacing the
references to these objects with
references to the copies. If a class
contains only primitive fields or
references to immutable objects, then
it is usually the case that no fields
in the object returned by super.clone
need to be modified.
Means when you have a subobject in your object you shouldnt just clone/copy its reference but the internal structure of this object (in order to create a new instance of it), if each object has its clean clone() methode you will be able to clone it like the parent object otherwise you will have to create a new instance of it and copy its internal premitive fields one by one.

What is this field-by-field copy done by Object.clone()?

In Effective Java, the author states that:
If a class implements Cloneable,
Object's clone method returns a
field-by-field copy of the object;
otherwise it throws
CloneNotSupportedException.
What I'd like to know is what he means with field-by-field copy. Does it mean that if the class has X bytes in memory, it will just copy that piece of memory? If yes, then can I assume all value types of the original class will be copied to the new object?
class Point implements Cloneable{
private int x;
private int y;
#Override
public Point clone() {
return (Point)super.clone();
}
}
If what Object.clone() does is a field by field copy of the Point class, I'd say that I wouldn't need to explicitly copy fields x and y, being that the code shown above will be more than enough to make a clone of the Point class. That is, the following bit of code is redundant:
#Override
public Point clone() {
Point newObj = (Point)super.clone();
newObj.x = this.x; //redundant
newObj.y = this.y; //redundant
}
Am I right?
I know references of the cloned object will point automatically to where the original object's references pointed to, I'm just not sure what happens specifically with value types. If anyone could state clearly what Object.clone()'s algorithm specification is (in easy language) that'd be great.
Yes, a field by field copy does mean that when it creates the new (cloned) object, the JVM will copy the value of every field from the original object into the cloned object. Unfortunately this does mean that you have a shallow copy. If you desire a deep copy, you can override the clone method.
class Line implements Cloneable {
private Point start;
private Point end;
public Line() {
//Careful: This will not happen for the cloned object
SomeGlobalRegistry.register(this);
}
#Override
public Line clone() {
//calling super.clone is going to create a shallow copy.
//If we want a deep copy, we must clone or instantiate
//the fields ourselves
Line line = (Line)super.clone();
//assuming Point is cloneable. Otherwise we will
//have to instantiate and populate it's fields manually
line.start = this.start.clone();
line.end = this.end.clone;
return line;
}
}
Also one more important thing about the cloning is, the constructor of the cloned object is never invoked (only the fields are copied). So if the constructor initializes an external object, or registers this object with some registry, then that will not happen for the cloned object.
I personally prefer to not use Java's cloning. Instead I usually create my own "duplication" methods.
It means a shallow copy -- the fields are copied, but if you have any references, what these point to is not copied -- you will have two references to the same object, one in the old object and one in the new, cloned object. However, for fields that have primitive types, the field is the data itself, so they get copied regardless.
newObj.x = this.x; //redundant
newObj.y = this.y; //redundant
that's right - these are redundant, since they will have already been copied by Object's clone() method.
Thinking of it as a data copy is correct. Primitive types are copied, and references are also copied so they point to the same object. For example,
class A implements Cloneable {
Object someObject;
}
A a = new A();
a.someObject = new Object();
A cloneA = (A)a.clone();
assert a.someObject==cloneA.someObject;
The default clone performs shallow copy of values. For primitive values, this is enough and no extra work is needed.
For objects, the shallow copy means copying the reference only. Therefore, in these cases a deep copy is usually needed. The exception for this is when the reference points to an immutable object. Immutable objects can't have their apparent state changed, therefore their references can be copied around safely. For example, this applies to String, Integer, Float, enumerations (if not made mutable by mistake).

Categories