Java是值传递还是引用传递?
首先,我们要知道值传递和引用传递的区别; 然后要了解Java中基本类型和引用类型的区别,以及Java中"="的作用; 最后我们再来判断Java到底是值传递还是引用传递。
一、值传递和引用传递
-
值传递:是指在调用函数时将实际参数复制一份到函数中,在函数中对参数修改的话,不会影响到实际参数。 引用传递:是指在调用函数时将实际参数的地址传递到函数中,在函数中对参数进行修改的话,将影响到实际参数。
二、基本类型和引用类型
-
基本类型:对于基本数据类型,值就直接保存在变量里面。例如图中的num,10直接保存在变量中。 引用类型:对于引用数据类型,变量保存的不是对象,而是对象的地址值(地址值是int / long类型的)。一般也称这个为“引用”,对象中保存着实际的内容,而引用则指向这个对象。
三、赋值运算符"="的作用
-
基本类型:对于基本类型,赋值运算符会直接改变变量的值。 引用类型:对于引用类型,赋值运算符会直接改变变量中的地址值。 但是原来的对象并不会被改变 。
若执行如下语句:
num = 20; str = "world";
-
当执行 num = 20 时,赋值运算符会直接改变变量 num 的值,将其改为 20 ; 当执行 str = "world" 时,赋值运算符会直接改变变量 str 中的地址,地址从 0x10 变为了 0x20 ,但是原来的对象 "Hello" 并没有被改变。(由于没有任何引用指向这个对象,所以在GC时会被JVM当作垃圾回收掉)
四、调用方法时发生了什么
1、基本类型
我们先给 num 赋值为10,然后调用方法 fun(int value) 在fun方法中,将 value 改为20 最后我们在最初的方法中输出num,发现它的值还是10
原因:因为调用fun()方法后,num 和value的值都是10,但valule是num的副本,所以在方法fun()中改变value的值后,原方法中num的值不会受到任何影响。
2、引用类型:提供了改变自身值的方法
- 我们先创建StringBuilder对象sb,并初始化它的值为 "Hello"
- 然后调用fun(StringBuilder builder)方法
- 在方法fun()中,我们使用对象本身的方法append来修改builder的值
- 回到最初的方法中,打印sb输出"Hello world"。我们发现sb的值被改变了
原因:调用fun()方法后,sb和builder其实都指向了同一个对象(如下图),此时builder使用方法改变值,其实就是对这个对象本身做了修改。由于sb也指向了这个对象,所以打印出的sb并不是"Hello",而是"Hello world"。
3、引用类型:提供了改变自身值的方法,但是不使用这个方法,而是使用了赋值运算符(=)
- 我们先创建StringBuilder对象sb,并初始化它的值为 "Hello"
- 然后调用fun(StringBuilder builder)方法
- 在方法fun()中,我们创建一个新的StringBuilder对象并初始化为" world",并使用赋值运算符
- 回到最初的方法中,打印sb输出"Hello",sb的值并没有被改变
原因:调用fun()方法后,sb和builder都指向了同一个对象。但是在fun()方法中创建了一个新对象,并使用赋值运算符(=),导致builder的地址被替换掉了。此时sb和builder指向的是不同的对象。 打印sb时,由于原对象"Hello"并没有被修改,所以sb的值并没有改变。
五、总结
在Java中:
-
如果参数是基本类型,传递的是基本类型的 字面量值 的拷贝; 如果参数是引用类型,传递的是该变量所引用的对象在堆中 地址值 的拷贝。
所以,Java中只有值传递。
参考文章
下一篇:
Java练手小游戏---黄金矿工