Java传递值理解
我想我知道它是传递到方法Java传递值理解,java,parameter-passing,Java,Parameter Passing,我想我知道它是传递到方法tricky()中的对象/数据成员的副本,因为重要的是值,而不是实际的对象本身。但是print语句向我保证,arg1和arg2拷贝确实在方法中切换。我不明白为什么这不能将信息传递回原始对象,从而切换它们;因为方法能够成功访问方法中的arg1.x和arg1.y数据成员 // This class demonstrates the way Java passes arguments by first copying an existing // object/data mem
tricky()
中的对象/数据成员的副本,因为重要的是值,而不是实际的对象本身。但是print语句向我保证,arg1
和arg2
拷贝确实在方法中切换。我不明白为什么这不能将信息传递回原始对象,从而切换它们;因为方法能够成功访问方法中的arg1.x
和arg1.y
数据成员
// This class demonstrates the way Java passes arguments by first copying an existing
// object/data member. This is called passing by value. the copy then points(refers)
// to the real object
// get the point class from abstract window toolkit
import java.awt.*;
public class passByValue {
static void tricky(Point arg1, Point arg2){
arg1.x = 100;
arg1.y = 100;
System.out.println("Arg1: " + arg1.x + arg1.y);
System.out.println("Arg2: " + arg2.x + arg2.y);
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
System.out.println("Arg1: " + arg1.x + arg1.y);
System.out.println("Arg2: " + arg2.x + arg2.y);
}
public static void main(String [] args){
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y);
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X1: " + pnt1.x + " Y1:" + pnt1.y);
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
}
}
对象引用被复制,复制的引用仍然指向内存中的同一对象。这就是为什么可以使用复制的参照更改对象。但是,修改参数引用将修改副本,而不是原始引用。这就是为什么重定向方法中的引用不会重定向传入的引用
希望这能澄清问题。Java确实通过值传递,但它传递的是对象引用的值,这提供了通过引用传递的效果(对于原语,它的行为更像是通过值传递)
但是Java始终是按值传递的。最初,您可以新建两个对象,这将打印以下内容:
X1: 0 Y1: 0
X2: 0 Y2: 0
调用tricky()时,通过值传入对pnt1和pnt2的引用,并将它们赋给arg1和arg2。因此,您正在传递内存中的位置。然后打印值:
Arg1: 100100
Arg2: 00
Arg1: 00
Arg2: 100100
当您使用temp进行交换时,您正在交换地址。因此,在主方法pnt1和pnt2中,仍然保留原始地址。因此,当您打印时,您会得到:
X1: 100 Y1:100
X2: 0 Y2: 0
这里有一个与一些其他背景相关的例子。我曾经用“图形方法”解释过这一点,所以我希望它能有所帮助。在
main
中,在调用tricky
方法之前,您有:
pnt1 -> Point(x=0; y=0)
pnt2 -> Point(x=0; y=0)
在tricky
方法中,arg1
和arg2
分别是pnt1
和pnt2
引用的副本,因此它们指向相同的对象:
pnt1 -> Point(x=0; y=0) <- arg1
pnt2 -> Point(x=0; y=0) <- arg2
然后,将temp
引用“指向”第一个点(100;100)对象。然后,使arg1
指向arg2
所指的同一对象-点(0,0),并使arg2
指向temp
已经指向的同一对象,即点(100;100)。因此,在棘手的方法中,您交换了所指的内存地址arg1
和arg2
pnt1 -> Point(x=100; y=100) <- arg2 (temp also pointing this object)
pnt2 -> Point(x=0; y=0) <- arg1
由于pnt1
和pnt2
方法中的所有更改都是在arg1
和arg2
上执行的,它们只是参考文件的副本,因此未按预期进行更改
因此,在tricky
中,您可以更改对象的内容(您有对它的引用),但不能修改对它的原始引用,因为您只有它的副本。因此Java是按值传递的(实际上是按值传递的引用)。Java是按值传递的,但是当我们传递一个对象引用时,引用值传递给方法,从那里方法可以更改对象成员的值
请看以下代码:
public class Passbyvalue {
public static void main(String[] args) {
// TODO code application logic here
Animal animal=new Animal();
animal.name="Dog";
System.out.println(animal.name);
testIt(animal);
System.out.println(animal.name);
}
public static void testIt(Animal animal){
animal.name="Cat";
}
}
输出
狗
猫
这是因为引用(原始和方法)都指向同一个对象
__________
| |
| |<------------- Orignal Reference
| Object |
| |<------------- Method Reference
| |
|__________|
输出:
狗
狗
现在,方法引用正在发布到堆中的另一个对象。@Lion不是true,原语是按值传递的。如果我没记错的话,所有对象都是按值传递的。实际上,Java的语义规定对象是按引用传递(-by value),基元类型是按值传递的。引用是按值传递的,基元是按值传递的。并没有其他类型的。你们可能想阅读这个问题。这很好地澄清了它。感谢澄清,Java对象是pass-by-reference-by-value.Um,不确定该术语的含义。Java绝对是按值传递的,对象是按引用传递的。引用是按值传递的,我想这就是你得到的。对象的值是它在堆/堆栈上的地址。当作为方法参数传递时,将在堆栈上分配一个新变量,并将地址放置在该变量中。我也听过术语“通过值引用传递”来描述这一点。重要的部分是,通过修改字段(直接或方法调用),您正在更改实际的对象数据,调用者将看到这一点。但是,方法内的重新分配将本地化为该方法。在C/C++中,您会得到一个带有&operator的引用,这在java中是没有等价的。不能说我听过按值传递引用,但您关于重新分配的观点说明了为什么它不是按引用传递。
public class Passbyvalue {
public static void main(String[] args) {
// TODO code application logic here
Animal animal=new Animal();
animal.name="Dog";
System.out.println(animal.name);
testIt(animal);
System.out.println(animal.name);
}
public static void testIt(Animal animal){
animal.name="Cat";
}
}
__________
| |
| |<------------- Orignal Reference
| Object |
| |<------------- Method Reference
| |
|__________|
public class Passbyvalue {
public static void main(String[] args) {
Animal animal=new Animal();
animal.name="Dog";
System.out.println(animal.name);
testIt(animal);
System.out.println(animal.name);
}
public static void testIt(Animal animal){
animal=new Animal();
animal.name="Cat";
}
}