优秀博客转发自:http://blog.csdn.net/zgz0627/article/details/50180971
java中只有值传递,不存在引用传递。无论是传值还是传地址都属于值传递。注意传地址并不是引用传递。
一、传值
1.代码示例:
- public class ValuePropagation
- {
- static void changeValue(int value)
- {
- value += 10;
- }
- public static void main(String[] args)
- {
- int num = 10;
- //未执行changeValue方法前num的值
- System.out.println(num);
- changeValue(num);
- //执行changeValue方法后num的值
- System.out.println(num);
- }
- }
2.结果:两次输出的结果是一样的,都是10并没有改变。
3.图解:
4.分析:num作为参数传递给changeValue(int value)方法时,是将内存空间中num所指向的那个内存单元中的值传递给changeValue(int value)中的参数value变量,而value这个变量也在内存空间中被分配的一个内存单元,changeValue(int value)中所有的操作都是对value所指向的那个内存单元的值进行操作,与num所指的那个内存单元不再有任何关系,所以两次输出的num值是一样的。
二、传地址
实例对象作为参数传递时,传递的是对象引用的副本,传的是地址值,现在该对象有两个引用都指向她,对象的内容可以在调用过程中被改变,但是对象的引用始终没有改变,对象引用为传递参数,引用没有改变,很明显这是值传递。
1.代码示例:
- class Person
- {
- public static String name = "Tom";
- }
- public class TransmitAdress
- {
- static void changeName(Person p)
- {
- p.name = "Jerry";
- }
- public static void main(String[] args)
- {
- Person person = new Person();
- //未执行changeName(Person p)前
- System.out.println(person.name);
- changeName(person);
- //执行changeName(Person p)后
- System.out.println(person.name);
- }
- }
2.结果:第一次输出的是Tom,第二次输出的Jerry。面对这样的结果,很多人很容易认为这是引用传递,通过下面的图解和分析你就会明白这也是值传递。
3.图解:
4.分析:主函数new了一个person对象,实际上分配了两个内存空间:一个在堆内存中,用来存放创建Person类的对象实体,一个在栈内存中,用来存放指向对象的引用变量person。0x345~0x348这段堆内存存放的是对象的实体,0x345是实体对象的首地址,而person所指向的栈内存中存放的值正是0x345,是实体对象的首地址,也就是说,person指向实体对象。当person作为参数传递给changeName(Person p)方法时,是将栈内存中person所指向的内存单元中存放的值复制给了参数p,也就是实体对象的地址传给了p,而参数p在栈内存中已经被分配了一个内存单元,changeName(Person p)中所有的操作都是对p所指的内存单元进行操作,与person所指向的内存单元没有关系了。所以说,这是值传递,而不是引用传递。