Reputation: 721
[Background note: I am a new Java programmer with a C++ background, so is a little confused about how arguments are passed around in Java.]
While reading and writing some code, I came to the following case
public class B{
int[] intArr;
Vector<String> strVec;
void mutator(){
// modifies intArr and strVec
}
}
public class A{
B bOfA;
A(B b){
bOfA = b;
}
void foo(){
bofA.mutator();
}
}
foo() in A definitely modifies bOfA, but what about b, the object that is passed in? Will its fields/data members be modified as well?
Are the fields shallow or deep copied?
Are strVec and intArr treated differently, because strVec is a container and inArr is an array, which might be implemented as some kind of pointers, therefore behave quite differently depending on if it is shallow or deep copied.
Thank you.
A (late) update with real code and somewhat surprising (I was assuming the pass-by-value mechanism interpreted in the C/C++ way) results:
import java.util.Vector;
public class B{
int[] intArr = null;
Vector<String> strVec = null;
int x = 0;
String s = null;
B(int sz){
x = 0;
s = new String("ini");
intArr = new int[sz];
strVec = new Vector<String>(sz);
for (int i=0; i<sz; i++){
intArr[i] = 0;
strVec.add( new String("xx") );
}
}
void mutator(){
x = -1;
s = new String("mute");
int sz = intArr.length;
strVec = new Vector<String>(sz);
for (int i=0; i<sz; i++){
intArr[i] = -1;
strVec.add( new String("aa") );
}
}
}
import java.util.Vector;
public class A{
B bOfA=null;
A(B b){
bOfA = b;
}
void foo(){
bOfA.mutator();
}
}
import java.util.Vector;
public class C{
public static void main(String[] args){
B b = new B(3);
A a = new A(b);
System.out.println("Contents of B before:");
System.out.println(b.x);
System.out.println(b.s);
for(int i=0; i<3; i++){
System.out.println(b.intArr[i]);
System.out.println(b.strVec.elementAt(i));
}
a.foo();
System.out.println("\n\nContents of A:");
System.out.println(a.bOfA.x);
System.out.println(a.bOfA.s);
for(int i=0; i<3; i++){
System.out.println(a.bOfA.intArr[i]);
System.out.println(a.bOfA.strVec.elementAt(i));
}
System.out.println("\n\nContents of B after:");
System.out.println(b.x);
System.out.println(b.s);
for(int i=0; i<3; i++){
System.out.println(b.intArr[i]);
System.out.println(b.strVec.elementAt(i));
}
}
}
And the results by cygwin:
Contents of B before:
0
ini
0
xx
0
xx
0
xx
Contents of A:
-1
mute
-1
aa
-1
aa
-1
aa
Contents of B after:
-1
mute
-1
aa
-1
aa
-1
aa
Upvotes: 2
Views: 273
Reputation: 726839
Arrays are reference objects. When you assign them, they are not copied at all - what happens there is similar to assigning an array to a pointer in C++.
When you copy an array using System.arraycopy
, a shallow copy is performed. Constructing a collection from another collection creates a shallow copy as well.
Note: Unlike C++ libraries, Java class libraries uses immutable classes a lot. For example, String
is immutable; so are the wrappers for numbers, such as Integer
. Immutability makes the shallow vs. deep copying a lot less relevant.
Another note: Vector<T>
should be used when you need a synchronized container; if you do not want synchronization, use ArrayList<T>
instead.
Upvotes: 2
Reputation: 26198
what about b, the object that is passed in?
Will its fields/data members be modified as well?
Since java by default is pass-by-value, object that is passed in the contructor is pass-by-value but its internally its fields within that object will have reference, therefore when you call bofA.mutator()
the B b
field will change as well.
To have deep copy you need to copy each of the field in the b object that was passed and use Arrays.copyOf()
.
Upvotes: 1
Reputation: 201487
Java passes everything by value. But, the value of Object(s) are references.
Both the array and the Vector are shallow copies.
Upvotes: 4