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";
    }

}