Java是按值传递的。这意味着被调用的方法作用于传入的对象的副本,而不是原始对象。
如果方法中没有更改对象,则创建实际副本似乎是不必要的。因此,实现程序以创建此类副本的编译器效率非常低。所有的Java编译器(javac,gcj,ECJ等)都真的这样做吗?
至少在声明参数final
的情况下,不复制是很有意义的。
修改
好的,所以不会复制对象。我感到困惑,因为String
是特殊的,因为它被复制(不可变)。抱歉我的不知情。只是为了弥补它,这是传递对象时发生的事情的第千个例子:
import java.lang.System;
class C { int member; }
public class Test {
static void subMethod(C object) { object.member=1; }
public static void main(String[] args) {
C object = new C();
object.member=0;
subMethod(object);
System.out.println(object.member); // prints "1"
}
}
答案 0 :(得分:3)
是的,Java始终是按值传递的。但是对于对象,它传递参考值。换句话说,对象不会被复制,但它的引用是。在方法中更改对象的属性也会将其更改为方法之外。
来自here,
但是,对象不会通过引用传递。正确的陈述是对象引用按值传递。
On-topic:编译器只是将引用复制到堆栈中的内存块。
答案 1 :(得分:2)
Java中的对象是引用,它是通过值传递的引用;这意味着Java是用于实际目的的对象传递。
修改强>
似乎我使用术语“实用目的”'引起很多争议,让我澄清一下。我只是意味着大多数人在想到“通过参考”时会想到什么。是传递值的更改是在该方法之外持久化的,这在Java中就是这种情况。 e.g。
void someMethod(SomeClass a) {
a.mutateState();
}
SomeClass a = new SomeClass();
someMethod(a); //passes reference to a by value;
a.methodInvolvingSomeState(); //mutations of object state persist to here, as if the previous call were pass-by-reference.
出于实际目的,这就是我所指的所有&#39 ;; OP的印象是a
的副本,我试图解释的不是真的。我完全清楚java是始终传递值,因此明确声明它是通过值传递的引用。正如评论中所指出的那样,很多时候它与实际传递引用不一样,并且我不打算表明其中任何一个都是可以用Java。