值传递与引用传递的理解一直不深,查看了很多的博客总结了自己的理解。如有错误,可以指出改正。
在了解引用传递之前,我们首先了解一下 什么是引用,其作用到底是什么?
可以说str这个变量是实例对象地址的一个别名
Java中数据类型分为基本类型的引用类型两大类
基本类型: byte、short、int、long、float、double、boolean、char 引用类型: 类、接口、数组
基本类型的变量在声明时就会分配数据空间 而引用类型在声明时只是给变量分配了引用空间,并不分配数据空间
注意: 在JAVA中所有的传递其实都是值传递,只不过区分于理解,加了引用传递而已。(其实在引用传递的时候,是把实参的地址传递给了形参而已)
运行结果:
a = 20 b = 10 num1 = 10 num2 = 20理解:在swap方法中,a、b的值进行交换,并不会影响到num1、num2。因为,a、b中的值,只是从num1、num2的复制过来的。 也就是说,a、b相当于num1、num2的副本,副本的内容无论怎么修改,都不会影响到原件本身。
输出结果:
0解析:
假设arr指向的内存地址是0x11 实参arr黑色,形参array红色。 调用change()的时候,形参array接收的是arr地址值的副本,此时的array也指向了0x11。 在change方法中对0x11地址里面的值进行了修改,导致0x11地址中存储的值变为了0。 所以输出为arr[0]输出结果为0
在看一段代码,我们都知道String和基本类型的包装类都是不可变类。
什么是不可变类? 就是该类被final修饰,创建了这个类的实例之后,就不容许改变他的值了。看一下这些的源码是否被final修饰。
在看如下的代码解析过程。
public static void main(String[] args) { String str = "Hello"; change(str); System.out.println(str); } public static void change(String s) { s = "wolrd"; }输出结果:
Hello发现是不是和我们理解的,有点有出入? 在调用change方法的时候,str把他的地址副本拷贝了一份给了s。 此时的str和s都指向了一个字符串常量"hello" 那么为什么s = "wolrd"的操作 并没有影响到str呢?
String的API中有这么一句话:“their values cannot be changed after they are created”, 意思是:String的值在创建之后不能被更改,因为String是不可变类 被final修饰的。 API中还有一段: String str = “abc”; 等效于: char data[] = {‘a’, ‘b’, ‘c’}; String str = new String(data); 也就是说:对String对象str的任何修改 等同于 重新创建一个对象,并将新的地址值赋值给str。
实际上,可以转换成一种理解。
public static void main(String[] args) { String str = "Hello"; change(str1); System.out.println(str1); } public static void change(String s) { char data[] = {'w', 'o', 'r','l','d'}; String str = new String(data); s = str; }然后引用指向的地址是。
class Person { String name; public Person(String name) { this.name = name; } } public class Test { public static void main(String[] args) { Person p = new Person("张三"); change(p); System.out.println(p.name); } public static void change(Person p1) { Person person = new Person("李四"); p1 = person; } }输出结果:
张三那么为什么输出结果是张三呢?看图。 在调用change方法的时候 p和p1指向通一个内存地址。 在change方法里面执行如下内容之后,p1的内存地址改变了。 Person person = new Person(“李四”);
最后的总结内容是: 值传递的时候,将实参的值,copy一份给形参。 引用传递的时候,将实参的地址值,copy一份给形参。 也就是说,不管是值传递还是引用传递,形参拿到的仅仅是实参的副本,而不是实参本身。
