【问题标题】:Can someone explain how java is pass by value only when有人能解释一下java是如何通过值传递的吗?
【发布时间】:2011-11-05 17:38:48
【问题描述】:

当我取一个数组时,是这样的:

int anArray[] = new int[5];
//initialize to 0

doStuff(anArray);

//inside doStuff
anArray[3] = 731;
//passes back to main

System.out.println(anArray[3]); // outputs 731

这不是引用传递吗?什么给了?

【问题讨论】:

标签: java pass-by-reference pass-by-value


【解决方案1】:

像数组这样的引用类型仍被视为按值传递,因为您传递的是引用值的副本。请注意,您没有传递实际的参考句柄。也就是说,您的 doStuff 方法不能像通过引用语义传递那样更改对 anArray 的引用。一个例子应该有助于理解差异:

int anArray[] = new int[] { 99, 100};

doStuff(anArray);
...

//inside doStuff 
anArray = new int[] { 68, 69};

...
// back in anArray's original scope
System.out.println(anArray[1]); // still outputs 100, not 69

【讨论】:

  • 或许澄清一下 - 您将无法将不同的数组分配给您的 anArray 引用并在 doStuff 方法之外查看它的效果。
【解决方案2】:

您的数组是一个存在于堆上(内存中某处)的对象。只要您的程序中至少有一个活动引用指向它,它就存在。

您可以将引用视为指向数组的链接或指针。引用通常只是一个很小的值,它告诉您的程序如何在其内存地址处访问您关心的对象。假设引用指向内存地址 100。当您将引用传递给方法时,它是按值传递的,因此该方法获取引用的副本。新值 100 进入方法。

当您尝试在该方法中对数组执行某些操作时,会考虑引用的值并将其用于访问内存中的对象。因此,我们查找地址 100,获取我们关心的对象并完成。

一旦你退出你的方法,方法内部的引用值就会消失(它是一个局部变量),但在方法外部你仍然有一个引用的副本,你仍然可以使用它来访问地址 100,其中你的对象是。

所以我们只是认为对象是通过引用传递的,而对象总是在内存中的同一个位置,我们只是传递一个被复制的引用值。由于副本与方法外部具有相同的值地址,因此我们可以访问相同的对象。

【讨论】:

  • 指针?谁说的指针?在谈论Java时,请不要谈论指针! :p
【解决方案3】:

您正在修改一个可变对象的状态,在本例中是一个数组。但是,当你尝试这段代码时,你会发现 doStuff 函数获取的是按值传入的数组:

public class try1
{

  static void doStuff(int[] anArray)
  {
    anArray = new int[] {
        5, 6, 7
    };
    System.out.println(java.util.Arrays.toString(anArray));
  }

  public static void main(String[] args)
  {
    int[] anArray = new int[] {
        0, 1, 2
    };
    System.out.println(java.util.Arrays.toString(anArray));

    doStuff(anArray);
    System.out.println(java.util.Arrays.toString(anArray));
  }

}

【讨论】:

    【解决方案4】:

    Java 是按值传递的。期间。

    方法得到的是变量内容值的副本,总是如此。这适用于基元和对象。在对象的情况下,变量的值是告诉 JVM 如何在堆内存中找到对象的地址。

    鉴于您的情况,开头的变量anArraydoStuff 函数内部的变量都持有相同的值,告诉JVM 如何在内存中检索相同的数组(只有一个)。就是这样。

    请注意,我什至不必使用“引用”这个词来给出这个答案......不,我在谈论 Java 时永远不会使用“指针”这个词。

    here 是关于按引用传递与值的大量讨论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 2016-06-13
      • 2023-03-03
      • 1970-01-01
      • 2019-10-24
      • 2017-12-26
      相关资源
      最近更新 更多