Java使用pass-by-value,包括Objects和primitive类型.因为Java传递了引用的值,所以我们可以更改目标的值但不能更改地址.
这与C++相比如何?
区别在于您是否可以影响调用函数中的变量.
让我们把对象搁置一会儿.在Java中,它纯粹是按值传递,您不能更改传递给被调用函数的变量的调用函数值.例:
void foo() {
int a = 42;
bar(a);
System.out.println("foo says: " + a);
}
void bar(int a) {
a = 67;
System.out.println("bar says: " + a);
}
Run Code Online (Sandbox Code Playgroud)
如果你打电话foo,你会看到:
bar says: 67 foo says: 42
bar无法改变foo的a.
如果你通过值传递,那么在C++中就是如此.但是,如果通过引用传递,则传递对调用代码变量的引用.这意味着被调用的代码可以改变它:
void foo() {
int a = 42;
bar(a);
cout << "foo says: " << a;
}
void bar(int& a) {
a = 67;
cout << "bar says: " << a;
}
Run Code Online (Sandbox Code Playgroud)
注意,它bar被定义为接收引用(int& a).如果你打电话bar,你会看到:
bar says: 67 foo says: 67
bar能够改变值的a范围内foo.
好吧,让我们处理对象引用:首先,请注意,正在使用的词"参考"两个完全不同的事情:一个参考的变量调用函数(这是通过按引用的东西),和引用一个对象.当您将对象引用传递给Java中的方法时,引用将按值传递,就像其他所有内容一样.
void foo() {
List list = new ArrayList();
List ref2 = list; // (Let's remember that object reference for later...)
bar(list);
System.out.println("foo says: " + list.size());
System.out.println("foo says: Same list? " + (ref2 == list));
}
void bar(List list) {
// `bar` can modify the state of the object the reference points to
list.add(new Object());
System.out.println("bar says (after add): " + list.size());
// ...but cannot change `foo`'s copy of `list`
list = new ArrayList();
System.out.println("bar says (after new): " + list.size());
}
Run Code Online (Sandbox Code Playgroud)
所以你看:
bar says (after add): 1 bar says (after new): 0 foo says: 1 foo says: same list? true
bar可以更改传入其引用的对象的状态(按值),但不能更改foo对该对象的引用.foo没有看到bar创建的新列表.