基本数据类型
Java
是一种强类型语言。也就是说在Java中必须为每一个变量声明一种类型。
Java
中有八中基本数据类型(primitive type),其中有4中整型、2中浮点类型、1种用于表示Unicode编码的字符单元的字符类型char
和一种表示真值的boolean
类型
Java
中有一个能够表示任意精度的算术包,称为‘“大数值”(big number)。虽然被称为大数值,但它不是新的Java
类型,而是一个Java
对象,在这里暂不做介绍。
- 整型
整型用于表示没有小数部分的数值,也就是我们数学中常常说的整数。Java
提供的四种整型如下表所示:
类型 | 二进制位数 | 取值范围 | 包装类 |
---|---|---|---|
byte |
8字节 | -128~ 127 | java.lang.Byte |
short |
16字节 | -32768~32767 | java.lang.Short |
int |
32字节 | -2147483648~2147483647 | java.lang.Integer |
long |
64字节 | -9223372036854775808~9223372036854775807 | java.lang.Long |
在实际开发中,经常根据数据的极值来选择合适的数据类型,既保证数值不会溢出,又要保障尽可能节省内存,所以要学会点点原理,知道数据的取值范围是怎么来的,在实际开发过程中就不用每次查资料了。
以byte
为例:byte
占八个字节,而在计算机中数据是以二进制的形式存储的,所以八进制的byte
的范围就是00000000~1000000,一共有2^8个数,所以byte的“容量”就是2^8=256,而在Java
中没有无符号类型(unsigned),byte的范围不仅包括了0和正数,还包括了负数,自然数和负整数各占一半,所以最小值就是-2^7-1 ,最大值2^7。int
\short
\long
同理。
附上代码:
// byte
System.out.println("基本类型:byte\t二进制位数:" + Byte.SIZE);
System.out.println("包装类:" + Byte.class);
System.out.println("最小值:Byte.MIN_VALUE:" + Byte.MIN_VALUE);
System.out.println("最大值:Byte.MAX_VALUE:" + Byte.MAX_VALUE);
// short
System.out.println("基本类型:short\t二进制位数:" + Short.SIZE);
System.out.println("包装类:" + Short.class);
System.out.println("最小值:Short.MIN_SIZE:" + Short.MIN_VALUE);
System.out.println("最大值:Short.MAX_SIZE:" + Short.MAX_VALUE);
// int
System.out.println("基本类型:int\t二进制位数:" + Integer.SIZE);
System.out.println("包装类:" + Integer.class);
System.out.println("最小值:Integer.MIN_VALUE:" + Integer.MIN_VALUE);
System.out.println("最大值:Integer.MAX_VALUE:" + Integer.MAX_VALUE);
// long
System.out.println("基本类型:long\t二进制位数:" + Long.SIZE);
System.out.println("包装类:" + Long.class);
System.out.println("最小值:Long.MIN_VALUE:" + Long.MIN_VALUE);
System.out.println("最大值:Long.MAV_VALUE:" + Long.MAX_VALUE);
输出结果:
基本类型:byte 二进制位数:8
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE:-128
最大值:Byte.MAX_VALUE:127
基本类型:short 二进制位数:16
包装类:java.lang.Short
最小值:Short.MIN_SIZE:-32768
最大值:Short.MAX_SIZE:32767
基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE:-2147483648
最大值:Integer.MAX_VALUE:2147483647
基本类型:long 二进制位数:64
包装类:java.lang.Long
最小值:Long.MIN_VALUE:-9223372036854775808
最大值:Long.MAV_VALUE:9223372036854775807
众所周知,Java
最大的特性就是跨平台,所以Java
程序要保证在所有机器上运行都要得到相同的结果,所以每一种数据类型的取值范围是固定的,避免在32位处理器上运行的程序在16位处理器上运行发生整数溢出的情况。
- 长整型有一个后缀L(例如:
40000000000L
) - 十六进制有一个前缀0x(例如:
0xABCD
) - 八进制有一个前缀0(例如:
010
对应八进制中的8) - Java 7开始,加上前缀0b就可以表示二进制数(例如:
0b1000
对应二进制的8) - Java 7开始,可以为数值字面量加下划线为了让人易读(例如:
1_000_000
对应十进制的一百万)
显然八进制表示会比较容易混淆,所以一般很少使用八进制常数
还是给段代码:
long aLong = 2147483648L;
byte a8 = 010;
int a16 = 0xABC;
byte b2 = 0b1000; // 二进制数
System.out.println(String.format("长整型long:%d\n八进制byte:%d\n十六进制int:%d\n二进制byte:%d", aLong, a8, a16, b2));
输出结果:
长整型long:2147483648
八进制byte:8
十六进制int:2748
二进制byte:8
有一点注意一下,声明
long
的值如果在int
值范围内,不加L是安全的,但如果值一旦超过int
所能接受的大小就会报错。如:long a = 123; // 实际上这个数还是一个int long b = 2147483648; // IDE提示:Integer number too large long c = 1000000000000L;
因为
long
类型的值如果不加L就还是int
类型,所以当值在int
范围内时,不会报错,但是当long
的值超过int的范围并且数值末尾没有加L的话就会提示Integer number too large
- 浮点类型
浮点类型用于表示有小数部分的数值。Java提供的两种浮点类型如下表所示:
类型 | 二进制位数 | 取值范围 | 包装类 |
---|---|---|---|
float |
4字节 | 1.4E-45~3.4028235E38(有效位数6~7位) | java.lang.Byte |
double |
8字节 | 4.9E-324~1.7976931348623157E308(有效位数15位) | java.lang.Short |
附上代码:
// float
System.out.println("基本类型:float\t二进制位数:" + Float.SIZE);
System.out.println("包装类:" + Float.class);
System.out.println("最小值:Float.MIN_VALUE:" + Float.MIN_VALUE);
System.out.println("最大值:Float.MAX_VALUE:" + Float.MAX_VALUE);
// double
System.out.println("基本类型:double\t二进制位数:" + Double.SIZE);
System.out.println("包装类:" + Double.class);
System.out.println("最小值:Double.MIN_VALUE:" + Double.MIN_VALUE);
System.out.println("最大值:Double.MAX_VALUE:" + Double.MAX_VALUE);
输出结果:
基本类型:float 二进制位数:32
包装类:class java.lang.Float
最小值:Float.MIN_VALUE:1.4E-45
最大值:Float.MAX_VALUE:3.4028235E38
基本类型:double 二进制位数:64
包装类:class java.lang.Double
最小值:Double.MIN_VALUE:4.9E-324
最大值:Double.MAX_VALUE:1.7976931348623157E308
double
这种类型的数值精度是float
的两倍,一般称double
为双精度数值,称float
为单精度数值。在程序中采用double
比较频繁,一般在需要快速处理单精度数据或者需要存储大量数据的情况下才使用float
。
对编程人员来说,
double
和float
的区别是double精度高,有效数字16位,float
精度7位。但double
消耗内存是float
的两倍,double
的运算速度比float
慢得多,能用单精度时不要用双精度,以省内存,加快运算速度。
-
float
类型的数值有一个后缀F,不可省略。 -
double
类型的数值后有一个后缀D,double
后缀D可省略。 - 没有后缀F的浮点数值默认为
double
。
所有浮点数遵循IEEE 754规范。有三个特殊的浮点数值表示溢出和出错的情况:
- 正无穷大
Double.POSITIVE_INFINITY
- 负无穷大
Double.INPOSITIVE_INFINITY
- NaN(不是一个数字)
例如:一个正整数除以0的结果为正无穷。0/0或者负数的平方根结果为NaN
。代码:
double x = Math.sqrt(-1.5f);
double y = 0.0f / 0; // 在Java中,允许浮点数运算时除数为0,所得结果是Infinity
if (Double.isNaN(x) && Double.isNaN(y)) {
System.out.println("x=" + x + ", y=" + y);
}
判断数值是否为
NaN
不能通过if(x == Double.NaN)
来判断(所有“非数值”的值都认为是不相同的,而对象引用的话,==判断引用所指的对象是否是同一个),应可以使用Double.isNaN(Double v)
来判断是否为NaN,使用Double.isInfinite(Double v)
来判断是否为正无穷或负无穷,Double.isFinite(Double v)
判断是否是有限的Double数值。
输出结果:
x=NaN, y=NaN
最后注意一点,浮点数值不适用于禁止出现舍入误差的金融计算中。例如:System.out.println(2.0-1.1);
的计算结果是0.8999999999999999
而不是我们想象中的0.9
。其原因是数值计算在计算机中仍然是以二进制的形式计算的,而二进制系统中无法精确地表示分数1/10
,就像十进制无法精确地表示1/3
一样。
如果需要在计算中不含有任何舍入误差,就应该使用
BigDecimal
类,在这里暂不做分析,将在后续笔记中分享相关内容。
-
char类型
char
类型用于表示单个字符,通常表示字符常量。例如:'A'
是编码为65所对应的字符常量。它与"A"
不同,"A"
表示的是包含字符A的字符串,想知道更多见ASCII编码。
Unicode编码单元可以表示为十六进制,其范围从\u0000
到\uffff
。例如:\u2122
代表注册符号(™),\u03C0
表示希腊字母π。
除了可以采用转义序列符\u
表示Unicode代码单元的编码外,还有一些用于表示特殊字符的转义序列符。所有转义序列符都可以出现在字符常量或字符串的引号内。例如,\u2122
或"hello\n"
。转义字符\u
还可以出现在字符常量或字符串的引号之外(而其他所有转义序列不可以)。例如public static void main(String\u005B\u005D args)
(\u005B
和\u005D
分别是[
和]
的Unicode编码)附所有的转义字符和所对应的意义:
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符''" | 092 |
\' | 代表一个单引号(撇号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 空字符(NULL) | 000 |
\ooo | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 1到2位十六进制所代表的任意字符 | 二位十六进制 |
拓展阅读:Unicode编码表。在Unicode出现之前,已经有许多不同的标准:美国的
ASCII
、西欧的ISO8859-1
、俄罗斯的KOI-8
、中国的GB18030
、BG2312
、GBK
、BIG-5
等。这样就导致两个问题:一个是对于任意给定的代码值,在不同的编码方案下有可能对应不同的字母;二是采用大字符集的语言其编码长度有可能不同。简而言之,经过一段时间不断改善,最终,在Java
中,char类型用UTF-16编码描述一个代码单元。
想了解更多编码的知识?Unicode 和 UTF-8 有何区别?、网页编码就是那点事
- boolean类型
boolean
(布尔)类型有两个值:false
和true
,用来判断逻辑条件。整型值和布尔值之间不能进行相互转换。
在一些编程语言中,
false
可以用0
来代替,true
可以用1
来代替,这在Java
中是不合法的。
引用数据类型
引用数据类型包括类class
、接口interface
和数组array
。
本部分内容说简单简单,说复杂复杂,所以我决定等后面我将到对象的时候再回过头来补充这部分内容,这样的话理解起来会更方便。所以本部分内容到此结束,等待后面更新吧!!
其他推荐阅读:
专题目录:【Java核心技术-基础篇】目录