Java数据类型和不同数据类型在JVM内存分配
1.java数据类型分类
Java语言是强类型(Strongly typed)语言,强类型包含两方面的含义:①所有的变量必须先声明,后使用;②指定类型的变量只能接受类型与之匹配的值。这意味着每个变量和每个表达式都有一个在编译时就确定的类型。
Java语言支持的类型有两类:基本类型(Primitive Type)和引用类型(Reference Type)。基本类型包括boolean类型和数值类型。数值类型有整数类型和浮点类型。整数类型包括byte、short、int、long、char,浮点类型包括float和double。引用类型包括类,接口和数组类型,还有一种特殊的null类型。所谓引用类型就是对一个对象的引用,对象包括实例和数组两种。实际上引用类型变量就是一个指针,只是java语言不在使用指针这个说法。空类型(null type)就是null值的类型,这种类型没有名称,所以不可能声明一个null类型的变量或者转换到null类型。空引用(null)是null类型变量唯一的值。空引用可以转换为任何引用类型。在实际开发中,程序员可以忽略null类型,假定null只是引用类型的一个特殊直接量。(注:空引用null只能被转换为引用类型,不能转换为基本类型,因此不要把null赋给一个基本类型的变量)
声明变量的语法:type varName[=初始值];
2.java不同数据类型在JVM中内存的存放位置
变量在JVM中内存的分配主要取决于变量的作用范围与变量的数据类型。
基本数据类型是放在栈中还是放在堆中,这取决于基本类型在何处声明,下面对数据类型在内存中的存储问题来解释一下:
2.1.在方法中声明的变量,即该变量是局部变量,每当程序调用方法时,系统都会为该方法建立一个方法栈,其所在方法中声明的变量就放在方法栈中,当方法结束系统会释放方法栈,其对应在该方法中声明的变量随着栈的销毁而结束,这就局部变量只能在方法中有效的原因。在方法中声明的变量可以是基本类型的变量,也可以是引用类型的变量。
(1)当声明是基本类型的变量的时,其变量名及值(变量名及值是两个概念)是放在JAVA虚拟机栈中
(2)当声明的是引用变量时,所声明的变量(该变量实际上是在方法中存储的是内存地址值)是放在JAVA虚拟机的栈中,该变量所指向的对象是放在堆类存中的。
2.2.在类中声明的变量是成员变量,也叫全局变量,放在堆中的(因为全局变量不会随着某个方法执行结束而销毁)。
同样在类中声明的变量即可是基本类型的变量 也可是引用类型的变量
(1)当声明的是基本类型的变量其变量名及其值放在堆内存中的
(2)引用类型时,其声明的变量仍然会存储一个内存地址值,该内存地址值指向所引用的对象。引用变量名和对应的对象仍然存储在相应的堆中。
3.Java不同数据类型在JVM中何时分配内存
3.1.成员变量:
当系统加载类或创建类的实例时,系统会自动为成员变量分配内存空间,并在分配内存空间后自动为成员变量指定初始值。基本数据类型默认初始值是0,引用数据类型默认初始值是null。
3.2.局部变量:
局部变量定义后,必须经过显示初始化后才能使用。这意味着定义了局部变量后,系统并未为这个变量分配内存空间,直到等到程序为这个变量赋值初始值时,系统才会给局部变量分配内存,并将初始值保存在这块内存中。
与成员变量不同,局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中。如果局部变量时基本类型变量,则直接把变量值存在栈中,如果是引用类型,则存放地址在栈中。
栈内存中的变量无须系统垃圾回收,变量是随方法或代码块的运行结束而结束的。因此,局部变量的作用域是从初始化该变量开始,直到该方法或该代码块运行完成而结束。因为局部变量只保存基本类型的值或对象的引用,因此局部变量所占的内存通常较小。
当我们定义一个成员变量时,成员变量将被放置到堆内存中,成员变量的作用域将扩大到类存在范围或者对象存在范围。这种范围扩大有两个坏处:
①增大了变量的生存时间,将导致更大的系统开销
②扩大了作用域,不利于程序的内聚性。