Java是否真的总是复制传递给方法的所有对象?

时间:2016-01-11 14:52:11

标签: java compiler-optimization pass-by-value

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"
    }
}

2 个答案:

答案 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。