3

可能重复:
Java 是按引用传递吗?
Java 通过引用传递

对于下面的 Java 程序,我的理解是它a是对 Integer 的引用类型,就像 C/C++ 中的指针类型。因此,方法中对其值所做的任何更改都f将在方法返回后反映出来。但println仍打印其原始值0而不是 3。

Integerint没有什么不同。是不是我之前的理解错了?请帮忙。谢谢!

  public static void f(Integer b){
            b=3;
        }
        public static void main(String[] args){
            Integer a=0;
            f(a);
            System.out.println(a);
      }
4

6 回答 6

4

Java 总是按值而不是按引用传递参数。


让我通过一个例子来解释这一点:

public class Main
{
     public static void main(String[] args)
     {
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }
     public static void changeReference(Foo a)
     {
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c)
     {
          c.setAttribute("c");
     }
}

我将分步骤解释:

  1. 声明一个名为ftype的引用并将Foo其分配给一个Foo具有属性的新类型对象"f"

    Foo f = new Foo("f");
    

    在此处输入图像描述

  2. 在方法方面,声明Foo了一个带有名称的类型的引用,a并且它最初被分配给null.

    public static void changeReference(Foo a)
    

    在此处输入图像描述

  3. 当您调用方法changeReference时,引用a将分配给作为参数传递的对象。

    changeReference(f);
    

    在此处输入图像描述

  4. 声明一个名为btype的引用并将Foo其分配给一个Foo具有属性的新类型对象"b"

    Foo b = new Foo("b");
    

    在此处输入图像描述

  5. a = b正在将引用重新分配给af属性为 的对象"b"

    在此处输入图像描述


  6. 当您调用modifyReference(Foo c)方法时,c会创建一个引用并将其分配给具有属性的对象"f"

    在此处输入图像描述

  7. c.setAttribute("c");将更改引用指向它的对象的属性,并且引用c指向它的对象是同一个对象f

    在此处输入图像描述

我希望您现在了解在 Java 中将对象作为参数传递是如何工作的 :)

于 2012-05-29T23:54:03.467 回答
2

该方法接收引用的副本。赋值不会改变整数表示的值(即使它想要也不能改变 -Integer在 Java 中是不可变的)。它只是设置b指向其他东西。指向的原始Integer对象a不受此更改的影响。

b = 3;

------    ------
|  a |    |  b |
------    ------
  |          |
  ------------
        |
   Integer(0)

b = 3;

------    ------
|  a |    |  b |
------    ------
  |          |
  |          |
  |          |
Integer(0)  Integer(3)

如果您想更改值,则必须改用可变类型。

有关的

于 2012-05-29T23:50:02.863 回答
2

Integer(与其他“基本”类一样)是不可变对象。这意味着没有方法可以更改该值。如果你这样做

 new Integer(1);

创建的对象将始终保持 1 值。

你当然可以

Integer a = new Integer(1);
a = new Integer(2);

但在这里你正在做的是创建两个对象,并依次为每个对象分配 a 。

调用该方法时,您将传递引用的副本a(如 edalorzo 所说),因此您所做的几乎相同(但不更改原始a引用)。

当然,很多类都不是一成不变的。在这些类中,您将拥有一个(或多个)允许您更改对象内部状态的方法,并且(只要您访问同一个对象)这些更改将由对象的所有引用“共享”(因为它们都指向同一个)。例如,假设 Integer 有一个setValue(int)方法,那么

public static void f(Integer b){      
        b.setValue(3);      
    }      
    public static void main(String[] args){      
        Integer a=0;      
        f(a);      
        System.out.println(a);      
  }    

会按您的预期工作。

于 2012-05-29T23:53:33.963 回答
1

整数是不可变的,因此通过引用传递不会按预期工作。请参阅Java:通过引用传递 int 的最佳方式

于 2012-05-29T23:49:20.020 回答
0

在 Java 中,一切都是通过副本传递的,在您的方法中,您链接的是引用,而不是它指向的实际对象。

于 2012-05-29T23:46:20.340 回答
0

您的理解是正确的,但整数是不可变的。如果要影响 Integer 变量的值,唯一的方法是创建一个新的 Integer 对象并丢弃旧的。因此,该声明b=3无效。

于 2012-05-29T23:50:17.183 回答