Java的数据类型共分为两大类:基本数据类型和复合数据类型。基本数据类型共有8种,分为4小类,分别是整型、浮点型、字符型和布尔型。整型和浮点型有时也合称为数值型。复合数据类型包括数组、类和接口。具体可见下表:
基本数据类型
- 整数类型
Java语言提供了4种整数类型:byte、short、int、long。这4种类型的字节大小和范围如下:
整型量可用十进制、八进制或十六进制形式表示,以1~9开头的数为十进制,以0开头的数为八进制,以0x或0X开头的数为十六进制。
- 浮点数类型
Java浮点数类型有两种:一种是单精度浮点数,用float关键字说明;一种是双精度浮点数,用double关键字说明。它们表示的范围如下:
如果数值常量中包含小数点、指数部分(字符E),或者数的后面跟有字母F或者D,则为浮点数。浮点型常量在默认情况下是double类型的,除非用字母F或f明确说明他是float类型的。浮点型常量中的字母F或D不区分大小写。
- 字符类型
单个字符用char类型表示。一个char表示一个Unicode字符,其值用16位无符号整数表示,范围为0~65535,。char类型的常量值必须用一对单引号(' ')括起来,分为普通字符常量和转义字符常量两种。
使用单引号括住一个字符,表示一个普通的字符常量。但有些字符在Java语言中有特殊的含义,表示时应使用转义字符:
- 布尔类型
逻辑值有两个状态,常被写作 on 和 off、true 和 false、yes 和 no 等。在Java中,用boolean类型表示这样的一个值,布尔类型也称作逻辑类型。boolean类型有两个常量值:true 和 false,它们全是小写。
Java是一门严格的语言类型,不允许数值类型和布尔类型之间进行转换。有些语言,如 C 和 C++,允许用数值表示逻辑值,如用 0 表示 false,非 0 表示 true。而Java就不允许这么做。
类型转换
整型、字符型数据可以混合运算,运算时,不同的数据类型先转换为同一数据类型,再进行运算。数据类型转换必须满足以下规则:
- 不能对boolean数据类型进行转换;
- 不能把对象类型转换为不相关的类对象;
- 在把容量大的类型转换为容量小的类型时,必须用强制类型转换;
- 转换过程中可能会导致溢出或损失精度,如:int i = 128; byte b = (byte) i; 由于 byte 类型的常量的取值范围是 -128 ~ 127,所以这里 b = 128就会溢出;
- 浮点数到整数的转换时舍去小数位,并不是四舍五入。如:float f = 3.7f; int i = (int) f; 这里 i 的结果为3。
- 自动类型转换
需要满足的条件:转换前的类型所占的位数小于转换后的类型所占的位数,例如 byte 类型占8位,int 类型占32位,因此 byte 类型可以自动转换为 int 类型。
// 自动类型转换
byte b = 11;
int i = b;
- 强制类型转换
需要满足的条件:
- 转换的数据类型必须是兼容的;
- 格式:type value = (type) source; type 是要转换的数据类型
// 强制类型转换
long val = 123L;
int i = (int) val;
基本数据类型对应的包装类
- 包装类
Java语言是一种面向对象的语言,但八种基本数据类型又并非对象,我们在实际使用中经常需要将基本数据转化成对象,便于操作。基本数据类型与对象类型最大的不同点在于,基本数据类型是数值,对象类型是基于引用。
扩展知识点:Java分为堆内存和栈内存,Java对象都在堆内存中存储。基本类型的变量在栈中直接存储的具体数值,对象类型的变量存储的是该对象在堆中地址的引用。
基本类型基于数值,所以基本类型是没有类而言的,是不存在类的概念的,也就是说,变量只能存储数值,而不具备操作数据的方法。对象类型则截然不同,变量实际上是某个类的实例,可以拥有属性方法等信息,不再单一的存储数值,可以提供各种各样对数值的操作方法,但代价就是牺牲一些性能并占用更多的内存空间。
为解决此类问题 ,Java为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes)。
基本数据类型对应的包装类如下图:
- 装箱和拆箱
在了解基本数据类型与包装类之间如何转换之前,先来了解两个基本概念:装箱和拆箱。
在Java SE5之前,如果要创建一个值为5的Integer对象,需要这么写:
Integer val = new Integer(5);
在Java SE5开始就提供了自动装箱功能,创建一个值为5的Integer对象只需这么写:
Integer val = 5;
这样写就会触发自动装箱,直接根据数值创建对应的Integer对象,而不再需要 new 操作。
int 转 Integer 为装箱,那么 Integer 转 int 则称为拆箱。
Integer val = 5; // 装箱
int i = val; // 拆箱
总之,装箱就是基本数据类型转换为包装器类型,拆箱就是包装器类型转换为基本数据类型。
- 装箱和拆箱的过程
首先编写一个java文件并保存(文件名要与类名一致,此处文件名为Test.java):
public class Test {
public static void main(String[] args) {
Integer val = 5; //装箱
int i = val; //拆箱
}
}
然后同目录下打开命令窗口,输入 javac Test.java 命令:
这时,该目录下会生成一个字节码文件Test.class。然后运行命令:javap -c Test.class
可以看到,装箱的时候调用了Integer的valueOf方法,拆箱的时候调用了Integer的intValue方法。
先看装箱过程:
可以看到,当 i 在 -128 ~ 127之间的时候,那么便返回指向IntegerCache.cache数组中已经存在的对象的引用;否则创建一个新的Integer对象。也就是,在创建Integer包装器时,有一个数值在[-128,127]的缓冲池。当创建的对象数值在[-128,127]之间时,那么不需要再在内存中开辟一个空间存储,只需要将当前对象的引用指向该缓冲池中对应的对象,这样效率上得到了提高,资源也没有浪费。
拆箱过程就比较简单了,直接return当前值:
以上就是本文对基本数据类型及其包装类的介绍,欢迎阅读及指正。