数据类型及不同种类的数据类型的存储方式
Java有八种基本数据类型
整型 byte、short、int、long
类型 | 存储需求 | 取值范围 |
byte | 1字节 | -128~-127 |
short | 2字节 | -32768~32767 |
int | 4字节 | -2147483648~2147483647 |
long | 8字节 | -9223372036854775808~9223372036854775807 |
浮点型
float、double
布尔型
boolean
字符型
char
创建Java文件时,类名文件名要一致,类名不能使用关键字命名,定义变量要采用小驼峰写法。
除去基本数据类型,还有引用数据类型
①数组(int[] a = {1,2,3})
②类(class)
③接口(interface)
基本数据类型和引用变量名是存储在栈中的
引用数据类型是存储在堆中的
基本数据类型的入栈流程
在栈中给入栈变量开辟一定的内存空间,变量入栈,寻找栈中有没有对应a的值的地址,如果有,则指向此地址,没有就另开辟一块地址,值为a的值,然后a中存储此地址。
那么这时就有一个问题出现了,如果只有变量,没有赋值呢。
对于全局变量(定义在类里面的是全局变量)来说,他的使用概率是极大的,所以,如果他没有被赋值,但是地址又不能为空,所以初始化时让他存储值为0的地址。但是对于局部变量(定义在方法里面的是局部变量),是不会进行初始化的,因为局部变量不一定使用,如果在栈中提前进行初始化,那么会占用一定的内存空间,所以要进行赋值,调用方法时使用。
这个时候可能会产生疑问,为什么地址不能为空呢?
这是因为内存和CPU要进行数据交互,而CPU的运算速度非常快,这就要求了在内存中的存储地址必须是连续的也就是要线性存储。
引用数据类型的入栈流程
main方法所在类先入栈,main方法入栈,这时定义一个对象,那么在内存中在栈中,为变量开辟内存空间,在堆中,开辟一个类的内存空间,这个内存空间包括类中的变量和方法(成员变量在堆中已经完成了初始化,不在栈中,如果没有赋值,则默认为0),然后就调用类中的方法,方法入栈…
和基本数据类型不同,基本数据类型如果值相同,则指向同一个地址,而引用数据类型,每新建一个对象,就会在堆中开辟一块新的内存空间。
关于基本数据类型和引用数据类型的参数传递
这里要提到一个概念,浅拷贝。
那么什么是浅拷贝,与之对应的还有深拷贝吗,是的,有。浅拷贝,只是复制了源对象的所有包括引用地址,而深拷贝,就意味着新对象和源对象相比,他们的引用地址发生变化,虽然长得一样,但是地址不同。
这里讲的是浅拷贝,浅拷贝中,引用数据类型传递的是地址,基本数据类型传递的是值。
参数传递的重点就是在于传递参数时是将变量复制一份,然后传入方法去执行。
关于值传递。
有的人会说了,为什么我将变量的值传入方法以后,改变变量的值,但是原来的变量的值为什么没有改变。
这是因为传递参数时,只是将值传递给了另外一个变量,这个变量传入到方法中去,改变值,改变的是这个所谓另外一个变量存储值的地址,和原来变量没有关系,所以没有发生改变。
关于地址传递。
那为什么我把地址传到方法里,改变对象的中的变量值,原来变量改变了呢?
这就是因为是地址传递,尽管传进方法中的变量和原变量是两个变量,但是他们都指向的同一个地址,地址中的变量发生了改变,原变量自然也会发生改变。
这个时候有一个问题,为什么字符串传递时,传进方法后,改变字符串的值,原来变量并没有改变呢。难道字符串是基本数据类型吗,
当然不是。这是因为,字符串存储在堆中的一个字符串常量池中,这是一个永久带,没有字符串会被回收,字符串也永远不会改变,如果变量的值改变了,那就另开辟一块新的内存空间存储新的字符串,原来的字符串不发生改变。
所以说,参数将字符串的地址传入方法中,在方法中改变变量的值,这时此变量指向的不再是原来的地址,而是另一个新的地址,原来的地址并不受影响,所以原变量的值并没有改变。