方法中的对象和原语

时间:2010-08-16 17:43:31

标签: java

请注意为什么用作方法参数的原语会在对象按原样使用时复制其值?

3 个答案:

答案 0 :(得分:6)

在Java中,所有参数都是按值传递的 - 但是对于引用类型(即除了基元之外的所有内容),变量的值不是对象本身 - 它是引用对象。因此,引用被复制到方法的参数中,因此它引用同一个对象。

请注意,这不仅适用于方法调用:

StringBuilder x = new StringBuilder();
StringBuilder y = x; // Copy the value of x, which is a *reference* 

y.append("Hello");
System.out.println(x); // Prints "Hello"

这里,xy引用相同的对象,即使它们是单独的变量。因此,当通过append变量通过y调用更改该对象的内容时,也会通过x变量显示更改。

我认为这有点像给某人你家的地址:如果我给两个人我的家庭住址,其中一个把门涂成红色,那么当第二个人到家时,他们会看到红门也是。我不给他们自己的房子,我给他们一个到我家的方式。

有许多关于此的文章 - 尽管不幸的是,有些人会声明通过Java引用传递对象。他们不是 - 正如我上面所说,参考文献是按价值传递的。 Scott Stanchfield有good article about this等等。

答案 1 :(得分:1)

为了扩展Jon Skeet所说的内容,原始类型通常非常小 - 双倍是8个字节。另一方面,对象可能是巨大的,因此传递对它们的引用可以节省时间和堆栈空间,而不是复制整个对象。另外,这允许您修改对象的内容。

答案 2 :(得分:1)

这就是它的样子但不是。 Java总是按值传递。

当你宣布这样的事情时:

Date aDate = new Date();

变量aDate实际上不是对象,而是对象引用。当您将该对象引用传递给另一个方法时,将传递该引用的“副本”(就像使用基元一样传递值的副本)

现在,由于这两个副本“引用”相同的底层对象,您会看到在其中一个上发送消息会影响另一个,但如果更改引用以指定新的引用,则另一个不会更改。

例如:

class Some {
    int data = 0;
}

class Other {
     void doSomething( Some o ) {
         o.data = 10;
     }
     void change( Some a ) {
         a = new Some();
         a.data = 1024;
     }
}
class Main {
    public static void main( String [] args ) {
        // create an object and get its object reference
        Some original = new Some();
        System.out.println( original.data ); // prints 0 

        // now pass it to a method from the class "Other"
        Other o = new Other();
        other.doSomething( original );


        System.out.println( original.data ); // prints 10, because data was changed in "doSomething"


        // To probe that the reference is not passed, but a copy of it
        // invoke the "change" method.
       other.change( original );

       System.out.println( original.data ); // remains 10, instead of 1024.

       // the value 1024 was changed in the new reference, and the one passed along 
       // didn't change. It still refers to the original object.
    }
}

我希望这会有所帮助