[背景说明:我是一名具有C ++背景的新Java程序员,所以对于如何在Java中传递参数有点困惑。]
在阅读和编写一些代码时,我遇到了以下情况
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();
}
}
A中的foo()肯定会修改bOfA,但是b,传入的对象呢?它的字段/数据成员也会被修改吗?
字段是浅还是深?
strVec和intArr的处理方式不同,因为strVec是一个容器而inArr是一个数组,它可能被实现为某种指针,因此根据它是浅层还是深层复制而表现完全不同。
谢谢。
使用实际代码进行(后期)更新,并且有点令人惊讶(我假设以C / C ++方式解释的按值传递机制)结果:
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));
}
}
}
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
答案 0 :(得分:4)
Java按值传递所有内容。但是,Object的值是引用。
两者数组和Vector都是浅拷贝。
答案 1 :(得分:2)
数组是引用对象。当你分配它们时,根本不会复制它们 - 这类似于在C ++中为数组分配数组。
使用System.arraycopy
复制数组时,会执行浅复制。从另一个集合构建集合也会创建一个浅表副本。
注意:与C ++库不同,Java类库使用不可变类。例如,String
是不可变的;数字的包装也是如此,例如Integer
。不变性使得浅层复制与深层复制的相关性低得多。
另一个注意事项:当您需要同步容器时,应使用Vector<T>
;如果您不想同步,请改用ArrayList<T>
。
答案 2 :(得分:1)
what about b, the object that is passed in?
Will its fields/data members be modified as well?
由于默认情况下java是按值传递,因此在构造函数中传递的对象是按值传递,但在内部,其对象中的字段将具有引用,因此当您调用bofA.mutator()
时{ {1}}字段也会发生变化。
要进行深层复制,您需要复制传递的b对象中的每个字段并使用B b
。