先看第一个例子
当八大基本类型作为参数传递时
package com.xuyifan.oop.demo01; import javax.crypto.BadPaddingException; /** * @author xyf * @create 2020-08-18-9:53 */ public class Test_02 { public static void main(String[] args) { int i=10; add(i); System.out.println(i+"这是main里的"); } public static void add(int i){ i++; System.out.println(i); } }
输出
11 10这是main里的
从栈内存图分析
我们知道,八大基本类型是保存在栈里的
当 int i作为参数进行传递时,将i的复制一份,传递给方法add()中的局部变量i,add方法中的i与main方法中的i有着不同的内存地址,虽然保存的值都是10,但是操作的时两块地址,add中的i也可以叫y,也可以叫z,add方法对于自身栈中i的操作不会影响到main方法中的i,所以,即使调用add(i),main中的i保存的值不变
那么当java对象作为参数进行传递时,情况会发生什么改变吗?
package com.xuyifan.oop.demo01; /** * @author xyf * @create 2020-08-18-9:15 */ public class Test { public static void main(String[] args) { Teacher teacher=new Teacher(); teacher.age=10; add(teacher); System.out.println(teacher.age); } public static void add(Teacher T){ T.age=11; System.out.println(T.age); } } class Teacher{ int age; }
输出
11 11
java的对象是再内存的 堆 中创建的
Teacher teacher =new Teacher();
Teacher类型的变量《teacher》在栈中保存了 new Teacher()在堆中创建的一个Teacher对象的内存地址,<teacher>自身也有一个栈中的内存地址,这个和基本变量是一样的
当teacher所引用的teacher对象作为方法参数被传递时,类似的,也是将变量 《teacher》内所保存的《Teacher对象》内存地址复制了一份,并赋值给方法中的Teacher类型的变量《T》
所以不论是变量《teacher》还是变量《T》,指向的都是堆中的同一个Teacher类型的java对象
在我们使用“ . ”操作符操作对象的属性时,都会相应的改变堆中teacher对象的属性
我们知道了,当java对象作为参数被传递时,传递的是堆中java对象的引用,实际上也就是复制了引用的值,赋值给新的引用,这个值就是java对象在堆中的地址
所以说,java的参数传递,本质上都是值传递