了解Java在用作方法参数时如何处理对象

了解Java在用作方法参数时如何处理对象,java,parameters,reference,parameter-passing,pass-by-reference,Java,Parameters,Reference,Parameter Passing,Pass By Reference,我一直在玩Java,不能完全理解Java方法如何处理传递给它们的对象 例如,在下面的代码中,我创建了一些“容器”对象实例,其中包含另一个对象和一个原语。当我将这个“Container”对象传递给方法时,我可以直接修改容器实例中保存的对象的值,或者使用new操作符来构造一个新对象并替换其原始对象。这些更改是永久性的,因为在方法外部检查时,它们的值是新对象的值 让我非常困惑的是,尽管我可以通过方法更改容器内部对象,但我无法实际更改容器本身。我的意思是,如果我将一个容器传递给一个方法,并尝试通过从ne

我一直在玩Java,不能完全理解Java方法如何处理传递给它们的对象

例如,在下面的代码中,我创建了一些“容器”对象实例,其中包含另一个对象和一个原语。当我将这个“Container”对象传递给方法时,我可以直接修改容器实例中保存的对象的值,或者使用new操作符来构造一个新对象并替换其原始对象。这些更改是永久性的,因为在方法外部检查时,它们的值是新对象的值

让我非常困惑的是,尽管我可以通过方法更改容器内部对象,但我无法实际更改容器本身。我的意思是,如果我将一个容器传递给一个方法,并尝试通过从new操作符交换或赋值来修改它

下面是我用来测试修改对象实例属性,然后修改实际实例本身的代码

类内部ref{
char-myChar;
InsideRef(char newVal){
myChar=newVal;
}
}
类容器{
InsideRef myInRef=null;
int myPrimitive=0;
容器(char innerChar,int innerPrim){
myInRef=新的内部ref(innerChar);
this.myPrimitive=innerPrim;
}
公开资料{
System.out.format(“Container.%s=>myPrimitive->%d | | myInRef=>%s->%c.%n”,
this.hashCode()、this.myPrimitive、this.myInRef.hashCode()、this.myInRef.myChar);
}
}
类attribrefmoder{
公共静态void ModObjRefVal(Container-toEdit){
toEdit.myInRef.myChar='Z';
}
公共静态void ModNewObjReference(Container-toEdit){
toEdit.myInRef=新内部ref('Y');
}
}
类引用交换程序{
公共静态void RefSwap(容器A、容器B){
System.out.println(“交换…”);
系统输出打印(“对象A->”);
A.我的详细资料();
系统输出打印(“对象B->”);
B.我的详细资料();
容器温度=A;
A=B;
B=温度;
系统输出打印(“交换A->”);
A.我的详细资料();
系统输出打印(“交换的B->”);
B.我的详细资料();
System.out.println(“退出…”);
}
公共静态void RefNew(容器A){
System.out.println(“分配引用新对象…”);
A=新容器('V',999);
系统输出打印(“新C参考->”;
A.我的详细资料();
System.out.println(“退出…”);
}
}
公共类引用排序{
公共静态void main(字符串[]args){
System.out.println(“--------------修改内部参考------------”;
容器C1=新容器('A',111);
系统输出打印(“原始A->”);
C1.myDetails();
attribrefmoder.ModObjRefVal(C1);
系统输出打印(“修改的A.参考->”;
C1.myDetails();
attribrefmoder.ModNewObjReference(C1);
系统输出打印(“新A.参考->”;
C1.myDetails();
System.out.println(“------------交换引用-----------------”;
集装箱C2=新集装箱('B',222);
RefSwapper.RefSwap(C1,C2);
系统输出打印(“对象A->”);
C1.myDetails();
系统输出打印(“对象B->”);
C2.myDetails();
System.out.println(“------------分配新对象-----------------”;
容器C3=新容器('C',333);
系统输出打印(“对象C->”);
C3.myDetails();
RefSwapper.RefNew(C3);
系统输出打印(“对象C->”);
C3.myDetails();
}
}
我道歉,如果这是太多的代码,我已经张贴。只是我整天都在玩Java,这个对象参数业务让我很困惑。我不明白为什么Java方法允许我编辑并将一个新对象分配给容器类中保存的
InsideRef
引用,但不允许我对实际的容器类执行相同的操作


感谢您提供的任何帮助。

您已经正确地说明了Java的特性

在封面下,传递对象的引用(内存地址是一个很好的模型)。因此,您可以更改该引用所引用的任何内容


但是你不能改变调用者所认为的“那个对象”——调用者有一个包含传递给你的地址的内存地址,你不能改变它。因此,无论您做什么,都不能更改引用的对象,只能更改该对象“内部”的内容。

您已经正确地说明了Java的特性

在封面下,传递对象的引用(内存地址是一个很好的模型)。因此,您可以更改该引用所引用的任何内容


但是你不能改变调用者所认为的“那个对象”——调用者有一个包含传递给你的地址的内存地址,你不能改变它。因此,无论您做什么,都不能更改引用的对象,只能更改该对象的“内部”内容。

在java中传递的参数始终是按值传递的。这意味着在赋值的左侧有一个参数在方法调用之外没有任何影响;它只是更改您在方法调用堆栈上复制的引用(指针)的值,因此您在方法的其余部分丢失了该值

例如,PL/SQL有一个通过引用传递的true参数,如果您在其中声明的话

-- True pass-by-reference
procedure my_procedure(my_integer out integer) is
begin
  my_integer := 6;
end;
在过程调用之后,您将看到您在那里传递的整数已更改其值。但是,java不支持此参数传递。在C中可以这样想:

// Just stepping on the values on the method call stack
void my_function(int* my_integer) {
   my_integer = 0;
}
这是否会更改指针引用的整数的值?不,它只是处理指针值。这就是你用你的钱做的

A = new Container('V',999);

我希望这对您有所帮助:)

在java中传递的参数是alwa
Container temp = A;
A = B;
B = temp;