数据类型
Java语言支持的类型分为两类:基本类型(Primitive Type)和引用类型(Reference Type)。
1. 基本数据类型

1.1 整数类型
若想把一个数值定义成long
类型,必须在其最后加一个l
或者L
字符为后缀(建议使用大写),不能直接以一个大的数字进行赋值,否则其依然被视为int
类型,若超出int
类型的范围会产生报错;
Java中整数值有4种表示方式:
十进制:无需多言。
二进制:以
0b
或0B
开头。八进制:以
0
开头。十六进制:以
0x
或者0X
开头,其中10~15
分别以a~f
(不区分大小写)来表示。
// 以0开头的整数值是八进制的整数
int octalValue = 013; // 表示十进制的数字11
// 以0x或0X开头的整数值是十六进制的整数
int hexValue1 = 0x13; // 表示十进制的数字19
int hexValue2 = 0XaF; // 表示十进制的数字175
如上所说,整数值默认是int
类型,因此使用二进制形式定义整数时,二进制整数默认占32位,其中第32位是符号位;如果在二进制整数后添加L
后缀,则其默认占64位,其中第64位为符号位。

1.2 字符类型
字符型通常用于表示单个的字符,其值必须使用单引号括起来,Java使用16位的Unicode字符集作为编码方式。(ASCII字符集8位,Unicode字符集16位)
字符型值也可以采用十六进制编码方式来表示,范围是'\u0000'~'\Uffff'
,一共可以表示65536个字符,其中前256个('\u0000'~'\u00ff'
)字符和ASCII码中的字符完全重合。
有一些特殊字符的转义序列,它们可以出现在加引号的字符字面量或字符串中,如下:
特殊地,
\u
还可以出现在加引号的字符常量或字符串之外,如public static void main(String\u005B\u005D args)
是合法的。
转义序列 | 名称 | unicode值 |
---|---|---|
\b | 退格 | \u0008 |
\t | 制表 | \u0009 |
\n | 换行 | \u000a |
\r | 回车 | \u000d |
\" | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\\ | 反斜杠 | \u005c |
一个隐秘的情况是,一定要小心注释中的\u
,比如以下会产生语法错误:
// \u000A is a newLine
:读程序时\u00A0
会替换为一个换行符,显然下一行不符合java语法。// look inside c:\users
:由于\u
后面并没有跟着4个十六进制数,所以报错。
由于计算机底层保存字符时,实际是保存该字符对应的编号,因此char
类型的值也可直接作为整型值来使用,它相当于一个16位的无符号整数,表示范围是0~65535。
1.3 浮点类型
浮点数必须包含一个小数点,否则会被当成int类型处理。
Java的浮点类型默认是double
类型,若希望将一个数字值当成float
型,需在其后加f
或者F
;当然,也可在一个浮点数后添加d
或D
,强制指定是double
类型,不过通常没有必要。
浮点类型的数值可以使用科学计数法形式表示,整型则不可。如,51200是一个int
类型的值,但512e2(或512E2)则是浮点类型的值。
Java提供了三个特殊的浮点数值,正无穷大、负无穷大、非数,用于表示溢出和出错。其中分别用Double
或Float
类的POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN
表示。必须指出的是:
- 所有的正无穷大值都是相等的,所有的负无穷大值都是相等的。
- 而
NaN
不与包括NaN
的任何数值相等。 - 一个整型值除以0,会抛出一个除0异常
ArithmeticException: / by zero
;但一个浮点数除以0,会得到无穷大或NaN
。
如果开发者需要精确保存一个浮点数,可以考虑使用BigDecimal
类。
对于整数/浮点类型,Java还可以在数值中使用下划线对数字进行分隔,以便更直观地分辨数值中到底包含多少位:
7
可以使用十六进制表示浮点数值,如$0.125=2^{-3}$可以表示成0x1.0p-3
。在十六进制表示法中,使用p
表示指数而不是e
,因为e
是一个十六进制数位。要注意的是,尾数采用十六进制,指数采用十进制,指数的基数是2,而不是10。
所以“非数值”的值都认为是不相同的。不过,可以使用类似Double.isNan
方法来判断:
if (Double.isNan(x)) {
// ...
}
在循环中检查两个浮点数是否相等需要格外小心,譬如下面的for
循环可能永远不会结束,因为由于浮点数舍入的误差,可能永远达不到精确的最终值:
for (double x = 0; x != 10; x += 0.1) // ...
1.4 布尔类型
Java规范没有强制指定boolean
类型的变量所占用的内存空间,虽然理论上其只需要1 bit即可保存,但大部分计算机在分配内存时允许分配的最小内存单元是字节,因此boolean
类型大部分时候占用8位。
Java中boolean
类型的数值只能是true
或者false
,不能用0或者非0来表示,其他基本数据类型的值不能转换成boolean
类型。
boolean
类型的值或变量主要用做旗标来进行流程控制。
2. 引用类型
引用类型就是对一个对象的引用,实际上就是一个C语言的指针,只是Java语言里不再使用指针这个说法。
对象包括实例和数组两种。
null
是一种特殊的引用类型——空引用,其被视为是引用类型的一种特殊的直接量。
2.1 字符串类型
Java没有提供表示字符串的基本数据类型,而是通过String
类来表示字符串,由于字符串由多个字符组成,因此字符串要使用双引号括起来:
// 下面代码定义了一个s变量,它是一个字符串实例的引用,它是一个引用类型的变量
String s = "沧海月明珠有泪,蓝田玉暖日生烟。";
通常情况下,字符串不能直接转换为基本类型,但可通过基本类型对应的包装类进行转换:
String a = "45";
// 使用Integer的方法将一个字符串转换成int类型
int iValue = Integer.parseInt(a);
在Java为8种基本类型都提供的对应的包装类中,每个包装类都提供了一个parseXxx(String str)
的静态方法用于将字符串转换成基本类型。
3. 基本类型的类型转换
基本类型的类型转换:当把一个表示范围小的数值或变量直接赋给另一个表数范围大的变量时,系统将进行自动类型转换;否则就需要强制转换。
3.1 自动类型转换
转换规则:

注意上图,其实byte
类型不能自动转换成char
类型,但可以自动转换为double
类型:
int a = 6;
// int类型可以自动转换为float类型
float f = a;
// 下面将输出6.0
System.out.println(f);
// 定义一个byte类型的整数变量
byte b = 9;
// 下面代码将出错,byte类型不能自动类型转换为char类型
// char c = b;
// byte类型变量可以自动转换为double类型
double d = b;
// 下面将输出9.0
System.out.println(d);
此外,当把任何基本类型的值和字符串值进行连接运算时,基本类型的值将自动转换为字符串类型,如:
String str = true + "";
// 下面将输出true
System.out.println(str);
//下面代码错误,因为5是一个整数,不能直接赋给一个字符串
// String str1 = 5;
// 一个基本类型的值和字符串进行连接运算时,基本类型的值自动转换为字符串
String str2 = 3.5f + "";
// 下面输出3.5
System.out.println(str2);
//下面语句输出7Hello!
System.out.println(3 + 4 + "Hello!");
// 下面语句输出Hello!34,因为`Hello! + 3`会把3当成字符串处理,而后再把4当成字符串处理
System.out.println("Hello! " + 3 + 4);
3.2 强制转换
想把自动类型转换图中箭头右边的类型转换为左边的类型,则必须进行强制类型转换,显然,这是一种“缩小转换”。其语法格式为:(targetType)value
强制类型对int
转换为byte
时,会截断int
的前24位,只保留右边的8位,此时剩余的8位中最左边的一个比特表示符号位:

3.3 表达式类型的自动提升
表达式类型的自动提升:当一个算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生自动提升,Java定义了如下的自动提升规则:
byte, short, char
类型均提升到int
类型;- 整个算术表达式的数据类型自动提升到与表达式中最高等级操作数同样的类型。操作数等级排列就是自动类型转换图,右边的类型等级高于左边的类型。