有人能解释一下java是如何通过值传递的吗?

发布于 2024-12-02 06:01:15 字数 244 浏览 1 评论 0原文

当我获取数组时,会出现这样的情况:

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

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

When I take an array, something like this:

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

Isn't this pass by reference? What gives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倥絔 2024-12-09 06:01:15

像数组这样的引用类型仍然被认为是按值传递,因为您传递的是引用值的副本。请注意,您没有传递实际的引用句柄。也就是说,您的 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

Reference types like arrays are still considered pass-by-value because you're passing a copy of the value of the reference. Note that you're not passing in the actual reference handle. That is to say, your doStuff method cannot alter the reference to anArray as would be possible in pass by reference semantics. An example should help understand the difference:

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
迷路的信 2024-12-09 06:01:15

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

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

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

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

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

Your array is an object which lives on the heap (somewhere in memory). It exists there as long as there is at least one active reference in your program pointing to it.

You can think of a reference as just a link or pointer to your array. The reference is typically just a small value that tells your program how to get to the object you care about at its memory address. Let's say the reference points to memory address 100. When you pass the reference to a method, it is passed by value, so the method gets a copy of the reference. A new value of 100 enters the method.

When you try to do something to the array in that method, the value of the reference is considered and used to gain access to the object in memory. So, we look up address 100, get the object we care about and finish.

Once you exit your method, the value of the reference inside the method disappears (it was a local variable), but outside the method you still have a copy of the reference, and you can still use it to access address 100 where your object is.

So we just get the perception that the object is passed by reference, when instead the object is always in the same place in memory, and we are just passing a reference value which gets copied. Since the copy has the same value address as outside the method, we can gain access to the same object.

九歌凝 2024-12-09 06:01:15

您正在修改可变对象(在本例中为数组)的状态。然而,当你尝试这段代码时,你会发现 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));
  }

}

You are modifying the state of a mutable object, in this case an array. However, when you try this code out, you will find that the doStuff function gets the array passed in by value:

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

}
两个我 2024-12-09 06:01:15

Java是按值传递的。时期。

方法获取的始终是变量内容值的副本。这对于基元和对象都适用。对于对象,变量的值是一个地址,告诉 JVM 如何在堆内存中查找对象。

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

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

关于引用传递与值传递的大量讨论位于此处

Java is pass by value. Period.

What a method gets is a copy of the value of the variable content, always. This holds true both for primitives and objects. In case of objects the value of the variable is an address that tells the JVM how to find the object in the Heap Memory.

Given your case, the variable anArray at the beginning and the one inside the doStuff function both hold the same value that tells the JVM how to retrieve the same array (there is only one) in Memory. That's it.

Note that I didn't even have to use the word "reference" to give this answer... And no, I'll never use the word "pointer" when talking about Java.

A huge discussion about pass by reference vs value is here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文