转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10830521.html
一:区分Java数据类型、变量类型
Java数据类型分两种:基本数据类型、引用类型。
8种基本数据类型(4整,2浮,1符,1布):byte(最小的数据类型)、short(短整型)、int(整型)、long(长整型);float(浮点型)、double(双精度浮点型);char(字符型);boolean(布尔型)。
引用类型类型:引用数据类型非常多,如:类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型。“简单来说,所有的非基本数据类型都是引用数据类型。”
变量类型:相应地,根据变量要存放的数据类型,也区分为:基本类型变量、引用类型变量。
基本类型和引用类型的区分,体现在其对应变量所存储的内容不同:
基本类型变量:变量存放的就是一个单纯的值。
引用类型变量:变量存放的是一个内存地址(引用),该地址指向内存中另一片地址,那片地址才是真正存放对象值的地方。
二:Java传参时的操作
我们在调用函数时,会将某些变量作为函数参数传递进去,调用方法时发生了什么?
这里涉及到形参和实参的概念:
1、在函数定义时所使用的参数,就是形参
定义函数时,函数参数只是作为一个变量、符号,体现在代码逻辑中,它没有具体的值。
2、在调用函数时,将值传给参数后,就是实参
在调用函数时,参数有了具体的值,变得有实际意义,此时称之为实参。
因此,参数传递的实质:就是 为函数形参赋值,使之变成实参数 的过程,也就是说:函数逻辑中所操作的并不是我们传进去的变量本身,而是copy了变量值的实参。
根据传递的数据类型以及函数中对参数的使用操作不同,大致可以分为4种场景:
1、基本数据类型传递
由于基本类型变量中存放的就是基本类型值,因此传递基本类型变量作为参数时,就是将变量的值,copy给了函数的实参。
因此,在函数中改变实参的值,不会影响函数外部的变量值。
2、immutable的引用类型变量传递
对于String,以及Integer、Double等几个基本类型包装类,它们的值是不可变的,也就是说:存放包装类类型的变量值,指向了一个对象地址,而这个变量不能再指向其他地址或存放别的值。
在immutable类型变量的传递过程中:会将变量值(引用地址)所指向的内容copy一份,并将复制后的空间的地址传递给函数作为实参。也就是说:传递给函数的变量所指向的空间,与函数实参所指向的空间是不同的,只不过各自指向的空间中的内容一样而已。
因此,函数中操作实参,不会影响到函数外部的变量值。
3、变量值可变的引用类型变量传递,并在函数中使用该引用去改变内容
对于class、array等普通引用类型,其变量值是一个地址,指向了这些对象真正存放的空间。“可变”的意思是:存放这些数据类型的变量,它可以所存储的地址,指向别的存储空间。
在这种类型的变量传递给参数的时候:会将变量值(引用地址)copy一份,传递给函数作为实参。也就是说:传递给函数的变量所指向的空间,与函数实参所指向的空间是相同的。
因此,在函数中通过实参去改变对象的内容,会影响到函数外部变量所指向的对象的内容,因为它们都指向同一个对象。
4、变量值可变的引用类型变量传递,但函数中为实参赋新值
与第3点不同,这种场景下,实参在函数中被更改了值,指向了新的地址。
因此,在后续操作中通过实参去改变对象的内容时,不会影响到函数外部变量所指向的内容,因为它们指向了不同对象。
三:结论——Java只有值传递
通过上文中关于“参数传递的实质”论述可以得知:函数调用时,无论值类型变量还是引用类型变量,都是将变量所存储的值copy给了函数的实参,区别在于基本类型变量的值就是类型值本身,而引用类型变量的值是一个地址。
也就是说:Java函数调用时,都是值传递。