Java中的按值传递与按引用传递

Java中的按值传递与按引用传递,java,Java,可能重复: 我试图理解下面编写的两个Java程序之间的区别: public class Swapping { public static void main(String[] args) { IntWrap i = new IntWrap(10); IntWrap j = new IntWrap(20); swap(i, j); System.out.println("i " + i.i + ", j " + j.i); } public static

可能重复:

我试图理解下面编写的两个Java程序之间的区别:

 public class Swapping {

public static void main(String[] args) {

    IntWrap i = new IntWrap(10);
    IntWrap j = new IntWrap(20);

    swap(i, j);
    System.out.println("i " + i.i + ", j " + j.i);
}

public static void swap(IntWrap i , IntWrap j){

    int x = i.i;
    i.i = j.i;
    j.i = x;

    System.out.println("i " + i.i + ", j " + j.i);
}

}

public class IntWrap {

int i;
public IntWrap(int i){
    this.i = i;
}

}
输出:

i 20, j 10
i 20, j 10
i 20, j 10
i 10, j 20
第二点:

public class Swapping {

public static void main(String[] args) {

    Integer i = new Integer(10);
    Integer j = new Integer(20);

    swap(i, j);
    System.out.println("i " + i + ", j " + j);
}

public static void swap(Integer i , Integer j){

    Integer temp = new Integer(i);
    i = j;
    j = temp;

    System.out.println("i " + i + ", j " + j);
}

}
输出:

i 20, j 10
i 20, j 10
i 20, j 10
i 10, j 20

我无法理解,即使我正在传递Integer对象,它也应该在原始程序中被交换。当我再次只传递对象时,如果我在其顶部编写包装器类,它会产生什么区别。

Ups<代码>整数对象在Java中是不可变的。您既不能从其他方法更改它们的内部值,也不能从任何方法更改它们的内部值。仅创建新的
Integer
对象。

Ups<代码>整数对象在Java中是不可变的。您既不能从其他方法更改它们的内部值,也不能从任何方法更改它们的内部值。只创建新的
Integer
对象。

所有方法参数,包括对象引用,在Java中都是按值传递的。您可以为方法参数指定任何值-调用代码中的原始值不会被修改。但是,您可以修改传递的对象本身,当方法返回时,更改将保持不变

J2SEAPI中有一些旧的Holder类,专门设计用于支持对具有“可返回参数”(例如,或)的方法的调用。它们主要用于从IDL语言生成的代码,因为IDL需要支持in、out和inout参数。这些持有者在其他代码中非常罕见

还可以使用数组模拟按引用传递:

String [] a = new String[1];  String [] b = new String[1];

void swap(String [] a, String [] b) {
   String t = a[0]; a[0] = b[0]; b[0] = t;
}

在Java中,所有方法参数(包括对象引用)都是按值传递的。您可以为方法参数指定任何值-调用代码中的原始值不会被修改。但是,您可以修改传递的对象本身,当方法返回时,更改将保持不变

J2SEAPI中有一些旧的Holder类,专门设计用于支持对具有“可返回参数”(例如,或)的方法的调用。它们主要用于从IDL语言生成的代码,因为IDL需要支持in、out和inout参数。这些持有者在其他代码中非常罕见

还可以使用数组模拟按引用传递:

String [] a = new String[1];  String [] b = new String[1];

void swap(String [] a, String [] b) {
   String t = a[0]; a[0] = b[0]; b[0] = t;
}

Java使用“按值调用”传递所有参数。当您将对象传递给函数时,对象引用(对象地址)将按值传递。在第二次程序交换中,您将分配i=j和j=temp。 所以i=20的地址 j=10的地址(新对象) 但从交换回来后,在主程序中,我仍然指向10,j指向20。这就是为什么你在主程序中得到10和20


但在第一个程序中,您将对象的地址传递给swap函数,并在swap函数中修改这些地址指向的对象的内容。这就是为什么它会反映在main方法中。

Java使用按值调用传递所有参数。当您将对象传递给函数时,对象引用(对象地址)按值传递。在第二次程序交换中,您将分配i=j和j=temp。 所以i=20的地址 j=10的地址(新对象) 但从交换回来后,在主程序中,我仍然指向10,j指向20。这就是为什么你在主程序中得到10和20

但在第一个程序中,您将对象的地址传递给swap函数,并在swap函数中修改这些地址指向的对象的内容。这就是为什么它会反映在main方法中。

(如果你不知道指针和参考资料,我建议你仔细研究一下,那么这个世界会更有意义-)

最简单的解释是,java有两种方式来回传递所有信息:

  • Pass by=Value:用于不可变对象(String、Integer、Double等))。如果重新创建对象,则这些值不能更改,只有一个例外

       String x = "World"; <- String x = new String("World");
       x = "Hello"; <- x = new String("Hello");
       x = x + " World"; <- x = new String("Hello" + " World");
       printOutString(x); <- printOutString("Hello World");
    
    String x=“World”(如果你不知道指针和引用,我建议你仔细检查一下,那么这个世界会更有意义-)

    最简单的解释是,java有两种方式来回传递所有信息:

    • Pass by=Value:用于不可变对象(String、Integer、Double等))。如果重新创建对象,则这些值不能更改,只有一个例外

         String x = "World"; <- String x = new String("World");
         x = "Hello"; <- x = new String("Hello");
         x = x + " World"; <- x = new String("Hello" + " World");
         printOutString(x); <- printOutString("Hello World");
      

      String x=“世界”
      整数i
      不是一个对象。它是对一个对象的引用。你是通过值传递引用。
      整数i
      不是一个对象。它是对一个对象的引用。你是通过值传递引用。他也可以看一看,解释得很好。他也可以看一看,解释得很好。谢谢这是最好的解释:)谢谢……这是最好的解释:)这并不是问题所在——在一种情况下,他修改了一个对象的字段,而在另一种情况下,他重新分配了一个对象。这对可变对象也会有同样的效果。@assylias可能我们对我的答案有误解。在第一种情况下,他只是更改
      IntWrap
      对象的字段值。没关系。在第二个例子中,他试图更改
      Integer
      对象的引用。他无法以其他方式处理
      Integer
      对象,因为它们具有不可变的性质(它们和bla-bla没有任何
      setValue
      )。但我同意,确实需要明确说明为什么他不能从其他方法更改引用。这并不是问题所在——在一种情况下,他修改了一个对象的字段,而在另一种情况下,他重新分配了一个对象。这对可变对象也会有同样的效果。@assylias可能我们对我的答案有误解。在第一种情况下,他只是更改
      IntWrap
      对象的字段值。没关系。在第二个例子中,他试图更改
      Integer
      对象的引用。他不能以另一种方式处理
      Integer
      对象,因为