JAVA详解传值和传址

关于java 传值和传址的问题,是一个讨论的比较多的话题,讨论的焦点不是传值或传址这两个概念本身,而是对于传值和传址的理解。我看了网上的很多博客,大部分的理解就是基础数据类型传值,引用数据类型传址,下面我通过示例采用画图的方式阐述对传址的理解:

示例一,代码清单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testRefer1(){
StringBuffer sbf = new StringBuffer("hello world");
changeRefer(sbf);
print(sbf);
}
public void changeRefer(StringBuffer sb){
sb.append(" changed");
}
void print(Object obj){
System.out.println(obj);
}

这个例子很简单,大部分人都知道sbf的值已经被改变了,下面画图说明:

图1

  • StringBuffer sbf = new StringBuffer(“hello world”); 在虚拟机栈中创建变量sfb,然后在堆中创建对象,再将对象的引用地址赋值给sbf

  • changeRefer(sbf); 在栈中拷贝一个sfb的引用地址的变量(假设叫sb),和sfb指向同一个对象

  • sb.append(“ changed”); 将sb指向的对象值改为 “hello world changed”

  • print(sbf); 打印 “hello world changed” ,因为sbf和sb指向的是同一个对象

示例二,代码清单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testRefer(){
StringBuffer sbf = new StringBuffer("hello world");
changeRefer(sbf);
print(sbf);
}
public void changeRefer(StringBuffer sb){
StringBuffer sbuf = new StringBuffer("hello world changed");
sb = sbuf;
}
void print(Object obj){
System.out.println(obj);
}

图例如下:

图2

  • StringBuffer sbf = new StringBuffer(“hello world”); 在虚拟机栈中创建变量sfb,然后在堆中创建对象,再将对象的引用地址赋值给sbf
  • changeRefer(sbf); 在栈中拷贝一个sfb的引用地址的变量(假设叫sb),和sfb指向同一个对象
  • StringBuffer sbuf = new StringBuffer(“hello world changed”);在虚拟机栈中创建变量sbuf ,然后在堆中创建对象,再将对象的引用地址赋值给sbuf
  • sb = sbuf;将sbuf的引用地址赋值给sb,所以此时sb指向了sbuf的对象,但是注意这个sb是sbf的拷贝引用变量,源变量sbf指向的对象不变
  • print(sbf); 打印 “hello world”

总结:其实就一点,在传参的时候,其实是有一个拷贝动作的,基础数据类型拷贝的是值,引用类型拷贝的是引用地址。

坚持原创技术分享,您的支持将鼓励我继续创作!
分享