Java 使用按值传递,包括对象和原始类型。因为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);
}
如果你打电话foo
,你会看到:
酒吧 说: 67 富 说: 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;
}
请注意,这bar
被定义为接收引用( int& a
)。如果你打电话bar
,你会看到:
酒吧 说: 67 富 说: 67
bar
能够改变within的值。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());
}
所以你看:
酒吧说(添加后):1 酒吧说(新之后):0 富 说: 1 foo 说:相同的列表?真的
bar
可以更改(按值)传入其引用的对象的状态,但不能更改foo
对该对象的引用。foo
没有看到bar
创建的新列表。
在 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);
}
如果你调用 foo,你会看到:
bar 说:67 foo 说:42 bar 不能改变 foo 的 a。
如果您按值传递,那么在 C++ 中就是如此。但是,如果您通过引用传递,您将传递对调用代码变量的引用。这意味着被调用的代码可以改变它:
在 C++ 中,与 Java 等价的是这个
void Swap(Type* A, Type* B)
{
// here we have pointers to type A (in Java they are called references and don't use * syntax)
A->DoThis() // can call with -> a method on object
//if you try to swap A with B not possible because we don't have A*/B* reference
// see bellow how to do this
}
在 C++ 中处理上述限制的方法是
void Swap(Type& A, Type& B)
{
Type& temp = A;
A = B;
B = temp;
}