在我了解细节之前,我想清楚地表明我确实理解Java是按值传递而不是传递参考,但是我有点困惑,因为我看到一些函数就是这样做的.我想知道他们是怎么做到的.
我想发生什么:
public void yo() {
int a = 1;
String b = "hello";
Boolean c = false;
doSomething(a,b,c);
// a,b,c should have new values
}
public void doSomething(int x, String y, Boolean z) {
// Do Something
}
Run Code Online (Sandbox Code Playgroud)
我见过的功能是这样的:
// Works in Android Development
int[] location = new int[2];
view.getLocationInWindow(location);
// `location` has a new value now
// Same happens when you run getLocationOnScreen(arg)
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?
首先:你是绝对正确的,Java纯粹是按值传递.
要记住的关键是当我们有一个类似于变量的变量location引用数组或对象时,变量实际上不包含数组或对象,它包含对内存中其他位置的数组或对象的引用.这是数组/对象和基元之间的最大区别.考虑以下代码:
int primitive = 5;
int[] ref = new int[2];
Run Code Online (Sandbox Code Playgroud)
这让我们记忆犹新:
+-----------+
| primitive |
+-----------+
| 5 |
+-----------+
+-----------+
| ref |
+-----------+ +--------+
| reference |----->| int[2] |
+-----------+ +--------+
| 0 |
| 0 |
+--------+
注意区别.那么上面的"参考"是什么?它是一个值,如123456789,VM用于在内存中定位数组.我们不知道价值,我们不关心它.我们关心的只是VM知道如何解释它.
因此,您引用的代码可以修改数组,因为传递给函数的值是对数组的引用的副本,而不是数组的副本.使用该引用来修改数组会修改该数组的一个副本,因此无论您使用哪个参考副本,都可以看到这些修改.
在此之后:
int[] location = new int[2];
Run Code Online (Sandbox Code Playgroud)
......我们在记忆中有这个:
+-----------+
| location |
+-----------+ +--------+
| reference |------>| int[2] |
+-----------+ +--------+
| 0 |
| 0 |
+--------+
然后,当你这样做:
view.getLocationInWindow(location);
Run Code Online (Sandbox Code Playgroud)
在内部getLocationInWindow,它接收一个引用的副本(因为Java是按值传递),所以说getLocationInWindow参数名称是foo,在调用期间我们有:
+-----------+
| location |
+-----------+ +--------+
| reference |---+-->| int[2] |
+-----------+ | +--------+
| | 0 |
| | 0 |
+-----------+ | +--------+
| foo | |
+-----------+ |
| reference |---+
+-----------+
通过引用的副本访问数组,访问同一个数组.(同样,对象引用也是如此.)
| 归档时间: |
|
| 查看次数: |
1611 次 |
| 最近记录: |