作者|王磊来源|Java中文社区(ID:javacn666)转载请联系授权(微信ID:GG_Stone)见正文证明。说到值传递和引用传递,就不得不提到两个概念:值类型和引用类型。1、值类型通俗的理解,所谓值类型是指Java中的8种基本数据类型:整型:byte、int、short、long浮点型:float、double字符型:char布尔型:boolean从JVM的角度来看:所谓值类型是指在赋值时直接在栈(Java虚拟机栈)上产生值的类型,如下图所示:2.引用类型Referencetype指值类型外部数据类型,如:classinterfacearraystringwrapperclass(Integer,Double...)从JVM层面,所谓引用类型是指初始化时在栈上产生引用,而value是在heap上生成的这些数据类型如下图所示:3.PassByValue是指方法传递参数时,传递的是原始内容的副本,所以对副本的任何修改都不会影响原有内容。实现代码如下:publicclassPassTest{publicstaticvoidmain(String[]args){intage=18;System.out.println("调用方法前:"+age);intTest(年龄);System.out.println("调用方法后:"+age);}privatestaticvoidintTest(intage){age=30;System.out.println("方法修改为:"+age);}}程序执行结果为:调用方法前:18方法中修改:30调用方法后:18从上面的结果可以看出,修改方法中的参数并没有影响原来的内容.我们称这种传递参数的方式为值传递。4.引用传递(PassByReference)是指方法传递参数时,传递的是参数本身,因此对参数的任何修改都会影响到原来的内容。模拟“引用传递”的实现代码如下:System.out.println("调用方法前:"+newString(name));参数测试(名称);System.out.println("调用方法后:"+newString(name));}privatestaticvoidparamTest(char[]n){n[1]='上帝';System.out.println("方法中修改:"+newString(n));}}程序的执行结果为:调用方法前:在雷哥方法中,方法改为:雷神调用方法后:雷神从上面的结果可以看出,在paramTest方法中修改参数后,在main方法中打印参数时,参数的值也随之改变。看来我们可以得出一个结论,Java好像也有“引用传递”,其实不然,我们看看。5.判断真假“按引用传递”我们在上面的代码中加一行,如下:};System.out.println("调用方法前:"+newString(name));参数测试(名称);System.out.println("调用方法后:"+newString(name));}privatestaticvoidparamTest(char[]n){n=newchar[2];//添加这行代码n[1]='God';System.out.println("方法修改为:"+newString(n));}}程序的执行结果为:调用方法前:雷哥,修改为:调用方法后:雷哥从上面的结果我们可以看出,当我们在paramTest方法中添加newchar[],"引用"pass"突然把值改成pass了?为什么?这是因为,在Java语言中,本质上只有值传递,也就是说Java的参数传递只会传递它的copy,而不会传递参数前面引用的“按引用传递”其实只是传递了它的引用副本,如下图:PS:《Java虚拟机规范》中Java堆的描述是:“所有的对象实例和数组都应该分配在heap”。所以我们在调用newchar[]之后,可以看到n对象有了新的地址,但是原来的内容并没有被修改。如果按照引用传递的思路来看,any修改会改变原来的内容,所以我们可以更加确定只有价值转移我在Java语言中,如下图所示:总结通过本文的内容,我们可以得出结论,在Java语言中,只能传递值,方法传递参数时,传递的只是复制信息,而不传递原始信息内容。我们也知道基本数据类型会直接在栈上生成,而对象或者数组会在栈和堆上同时生成信息,而在栈上生成的引用会直接指向堆上生成的数据,如图在下图中:
