mar*_*ary 0 java pass-by-reference
为什么以下代码输出等于0?
public class A{
public static void main(String [] args){
int a=0;
foo(a);
System.out.println(a);
}
public static void foo(int a){
a=78;
}
}
Run Code Online (Sandbox Code Playgroud)
它输出0是因为这a是main函数中的值.Java 完全是按值传递的,它根本没有传递引用.所以,当你打电话foo时,值中的a变量传入foo,不给一个参考a变量.foo然后修改其 a参数的值,但这对a变量没有任何影响main.
你可能会听到人们谈论"按价值传递参考"或"参考价值传递",这可能令人困惑,我强烈建议避免像瘟疫这样的术语.:-)但这是他们在谈论的:
在您的示例中,a是一个原语.该a变量包含的值0.但同样,你可以这样做:
Object a = new Object();
foo(a);
Run Code Online (Sandbox Code Playgroud)
什么传递到foo现在?没错,当它是一个已传递了同样的事情int:该值的a.唯一的区别是,现在,该值的a是一个对象引用.对象引用就像其他任何值一样; 它们告诉JVM对象的数据在内存中.把它们想象成一个大阵列或类似的索引.
那么:
int a = 42;
Run Code Online (Sandbox Code Playgroud)
在内存中给我们这个:
+---------+ | a | +---------+ | 42 | +---------+
这个
Object a = new Object();
Run Code Online (Sandbox Code Playgroud)
......给我们这个:
+---------+ | a | +---------+ +-----------------+ | mumble |------------>| The object data | +---------+ +-----------------+
重要的是要理解它a仍然只包含一个值,就像它包含一个int或一个float.正是这个值的含义不同,就像inta所持有的值的含义不同于a所持有的值的含义一样float.在对象引用的情况下,值的含义是"对象在那里".
就像你可以拥有多个保存值的变量一样42,你可以拥有多个变量来保存对同一个对象的引用:
int a, b;
a = 42;
b = a;
Run Code Online (Sandbox Code Playgroud)
给我们
+---------+ +---------+ | a | | b | +---------+ +---------+ | 42 | | 42 | +---------+ +---------+
等等
Object a, b;
a = new Object();
b = a;
Run Code Online (Sandbox Code Playgroud)
给我们
+----------+ +----------+
| a | | b |
+----------+ +----------+
| mumble |--+--| mumble |
+----------+ | +----------+
|
|
| +-----------------+
+--->| The object data |
+-----------------+
a并且b仍然只包含值,如42; 但是该值告诉JVM对象所在的位置,因此它们引用(指向)同一个对象.
再回到foo,当你调用一个函数,传入的参数是完全相同就像另一个变量赋值的变量,所以认为b上面的foo函数参数.
在下面的评论中,您已经询问了数组.数组就像对象 - 或者它们是对象; 选择你喜欢的语义.:-)所以:
int[] a;
int[] b;
a = new int[5];
b = a;
Run Code Online (Sandbox Code Playgroud)
给我们:
+----------+ +----------+
| a | | b |
+----------+ +----------+
| mumble |--+--| mumble |
+----------+ | +----------+
|
|
| +----------------+
+--->| The array data |
+----------------|
| [0]: 0 |
| [1]: 0 |
| [2]: 0 |
| [3]: 0 |
| [4]: 0 |
+----------------+
所以考虑:
public static final void main(String[] args) {
int[] a = new int[5];
foo(a);
System.out.println(a[0]);
}
void foo(int[] b) {
b[0] = 42;
}
Run Code Online (Sandbox Code Playgroud)
那打印42.为什么?由于值的a通入foo,所以b内foo指向相同的数组a指向.您可以使用引用更改对象的状态.请注意,您没有更改值b,您正在更改b引用的东西的状态.
对比:
public static final void main(String[] args) {
int[] a = new int[5];
foo(a);
System.out.println(a[0]);
}
void foo(int[] b) {
b = new int[5]; // <==== change here
b[0] = 42;
}
Run Code Online (Sandbox Code Playgroud)
现在它打印0,因为你已经为其分配了一个新值(一个新的对象引用)b,这对值所持有的值a或a值所引用的值没有影响.