Java值传递和引用传递详解

关于Java的值传递咱们知道:Java中基本类型做为函数参数传递就是值传递,不管在函数中对传进去的值作什么操做,函数外面声明的变量值都不会有什么改变,而对象做为函数参数传递进去则否则,为何说否则呢,请看下面的代码。
bash

下面的代码中有三个函数,一个值传递,两个引用传递app

package com.learn;

public class main {

    public static void change(int data){//值传递

        data = data+1;
    }
    public static void changeref(StringBuffer data){//引用传递1
        data = new StringBuffer("in changeref");
    }
    public static void changeref_2(StringBuffer data){//应用传递2
        data.append(" now changed");
    }
    public static void main(String[] args){

        int num = 10;
        System.out.println("num before changed: "+num);
        change(num);
        System.out.println("num after changed: "+num);


        StringBuffer str = new StringBuffer("outside");
        System.out.println("str before changed: "+str);
        changeref(str);
        System.out.println("str after changed: "+str);



        StringBuffer str_2 = new StringBuffer("outside");
        System.out.println("str_2 before changed: "+str_2);
        changeref_2(str_2);
        System.out.println("str_2 after changed: "+str_2);

    }


}
复制代码


num before changed: 10
num after changed: 10
str before changed: outside
str after changed: outside
str_2 before changed: outside
str_2 after changed: outside now changed

Process finished with exit code 0
复制代码

从代码的运行结果能够看到,不出意料的,咱们能够看到基本类型int的值在通过函数操做后没有任何变化,而一样是引用传递str与str_2的结果却彻底不一样,这是为何呢?jvm

回到代码,能够发现,changeref()函数中data直接指向了一个新的StringBuffer对象,通过此操做后函数外的str值并无任何改变,而changere_2()函数中data是日后追加了一段字符串,此操做后函数外的str_2值改变了。这是为何呢?ide

在讨论这个问题以前,先来讨论一下什么是值传递,什么是引用。首先值传递的概念是将值复制一份传入函数。而引用的概念就涉及到了jvm存储模型,在jvm存储模型中,基本类型都是直接存在Java虚拟栈中的,而对象都是新建在堆区,要想访问位于堆区的对象,须要在Java虚拟栈中创建一个变量,它的值是:指向某个对象的地址,这个变量就是引用。函数

而在Java中并无真正的引用传递,一般所说的引用传递其实也是值传递。而在上面的代码中,changeref()直接改变data的值是对复制过来的引用值进行改变,changeref_2()是对data指向的对象进行操做,换言之就是对堆中的对象进行改变,因此就出现这样的结果。ui

相关文章
相关标签/搜索