值传递和引用传递

值传递和引用传递

在说这个问题之前首先我们需要明确java中对象变量的存储:

例如:People p=new People();

              首先在堆中建立People对象

              然后在栈内存中建立变量p,并使p指向People对象在堆中的地址,也就是说p中保存的是People对象的堆地址,p为People对象的引用

当p作为函数参数时传递的是其保存的地址;

接下来我们看两个例子:

一、

public class RefrenceOrValue {

    static void test1(StringBuffer str)

    {

        str=new StringBuffer("hello world");

    }

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        StringBuffer str=new StringBuffer("you are handsome");

        System.out.println(str);

        test1(str);

        System.out.println(str);

    }

}运行结果:

you are handsome

you are handsome

结果并没有改变str的值

二、

public class RefrenceOrValue {

    static void test2(StringBuffer str)

    {

        str.append("str改变了");

    }

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        StringBuffer str=new StringBuffer("you are handsome");

        System.out.println(str);

        test2(str);

        System.out.println(str);

    }

}

结果:

you are handsome

you are handsomestr改变了

结果str的值改变了

分析:test1()和test2()中都接收了str的值,回顾对象的存储,str的值就是"you are handsome" 字符串对象的地址。在接收str值主要有下面的过程:成员变量str将它的值传递给形参str(注意:两个str并不是同一个变量,成员变量str是在堆内存中分配空间,而形参str是在栈中分配空间)但是这里传递的是对象的地址(类似c中的指针);

Test1()中str=new StringBuffer("hello world");实际上是将形参str的指向改变了,对成员变量str没有影响

test2()中str.append("str改变了")因为将实参(也就是成员变量str)的值传递给了形参str,所以实参和形参都同时指向了"you are handsome"这个对象,那通过两者更改他们指向的内容效果是一样的

 

主要抓住实参与形参是两个不同的变量,但是因为对象的引用保存的是对象的地址,所以通过实参与形参修改对象内容效果是一致的,但在函数体中又修改了形参的指向那就不能更改实参指向的对象了

 

将例一中的StringBuffer对象改为String类型对象其结果也不会改变,原理与上述相同,并不是因为String类型变量是一个固定值这个原因

public class RefrenceOrValue {

    static void test1(String str)

    {

        str=new String("hello world");

    }

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        String str="you are handsome";

        System.out.println(str);

        test1(str);

        System.out.println(str);

    }

}

结论:在java中对象作为形参时传递的是对象的引用值;对于这类问题还需要注意,实参与形参是不同的两个变量,形参为实参的浅拷贝也叫副本(即两者的指向相同),但形参的指向在函数体内部是可能改变的。浅拷贝可以参考博客中计算机基础内容

原文地址:https://www.cnblogs.com/zhaolei1996/p/10575398.html