01. Java 中的数据类型
数据类型
Java 是一门强语言,语言的数据类型分为:八种基本类型和三种引用类型(数组, class, interface)。在声明变量或常量时必须指定数据类型。
整数类型
Java 中整数类型都是有符号型。
整型分为int(默认), byte、short、int 和 long 四种类型,它们之间的区别仅仅是宽度和范围的不同。
- byte 的范围 1 字节 -128 到 127
- short 的范围 2 字节 -32768 到 32767
- int 的范围 4 字节 -2147483648 到 2147483647(约 21 亿)
- long 的范围 8 字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
为方便查看数值类型的最大和最小值, Java 提供了对应了静态成员变量。例如 Integer.MAX_VALUE 和 Integer.MIN_VALUE。
实型(小数类型 / 浮点型)
存储格式
浮点格式采用 阶码 + 尾码 的方式。
- 浮点型常量后面加后缀修饰,Float 类型以 F/f 结尾,double 类型以 D/d 结尾。
- 如果浮点常量不带后缀,则默认为双精度常量
二进制中为表示小数,也采用类似的科学表示法,形如 m×(2^e)。m 称为尾数,e 称为指数。指数可以为正,也可以为负,负的指数表示那些接近 0 的比较小的数。在二进制中,单独表示尾数部分和指数部分,另外还有一个符号位表示正负。几乎所有的硬件和编程语言表示小数的二进制格式都是一样的。这种格式是一个标准,叫做 IEEE 754 标准,它定义了两种格式:一种是32位的,对应于 Java 的 float;另一种是 64 位的,对应于 Java 的 double。
32 位格式中,1 位表示符号,23 位表示尾数,8 位表示指数。
64 位格式中,1 位表示符号,52 位表示尾数,11 位表示指数。
在两种格式中,除了表示正常的数,标准还规定了一些特殊的二进制形式表示一些特殊的值,比如负无穷、正无穷、0、NaN(非数值,比如 0 乘以无穷大)。IEEE 754 标准有一些复杂的细节,初次看上去难以理解,但也不常用。
1、Float:比特数为 32,数值范围为 -3.4E+38 ~ 3.4E+38
2、Double:比特数为 64,数值范围为 -1.7E-308~1.7E+308
1 | // 三者都是一回事 |
无论是使用 float 还是 double,进行运算时都会出现一些非常令人困惑的现象,比如 0.1f * 0.1的结果看上去应该是 0.01,但实际上,屏幕输出却是 0.010000001,后面多了个 1。
二进制是类似的,但二进制只能表示那些可以表述为 2 的多少次方和的数。为什么计算机中不能用我们熟悉的十进制呢?在最底层,计算机使用的电子元器件只能表示两个状态,通常是低压和高压,对应 0 和 1,使用二进制容易基于这些电子元器件构建硬件设备和进行运算。如果非要使用十进制,则这些硬件就会复杂很多,并且效率低下。
计算不精确,怎么办呢?大部分情况下,我们不需要那么高的精度,可以四舍五入,或者在输出的时候只保留固定个数的小数位。如果真的需要比较高的精度,一种方法是将小数转化为整数进行运算,运算结束后再转化为小数;另一种方法是使用十进制的数据类型,这个并没有统一的规范。在 Java 中是 BigDecimal,运算更准确,但效率比较低。
数字表示方式
不同的进制数
Java中对整型数据的表示有以下三种形式:
- 二进制:数据以
0b
或0B
开头(jdk 1.7新增)。 - 八进制:数据以
0
开头,例如:054
,012
- 十六进制:数据以
0x
或0X
开头,例如:0x11
,0xAD00
二进制写起来太长,为了简化写法,可以将 4 个二进制位简化为一个 0~15 的数, 10~15 用字符 A~F 表示,这种表示方法称为十六进制。
指数表示
进行数学计算时往往会用到指数表示的数值。如果采用十进制表示指数,需要使用大写或小写的 e 表示幂。
1 | System.out.println(1e2);// 100.0 |
在使用十六进制数的时候也是可以使用科学计数法,只是此种用法用得不多
1 | // 表示十六进制12 乘以 (2 的 2次方) = 18 * 4 = 72 |
在 Java SE 7 中,还支持以下划线作为分隔符联接的数值表示方式,但是下划线不能放在首尾的位置
输出样例
1 | System.out.println(123_456); |
字符类型
Java中 char 声明字符类型,且必须用单引号括起来的单个字符。这个字符可以是中文字符,也可以是英文字符。赋值时把常量字符用单引号括起来。
在 Java 内部进行字符处理时,采用的都是 Unicode,具体编码格式是 UTF-16BE。简单回顾一下,UTF-16 使用 2 个或 4 个字节表示一个字符,Unicode 编号范围在\u0000(即为 0)到 \uffff(即为 65535),占两个字节。超出范围的占 4 个字节,BE 就是先输出高位字节,再输出低位字节,这与整数的内存表示是一致的。
char 本质上是一个固定占用两个字节的无符号正整数,这个正整数对应于 Unicode 编号,用于表示那个 Unicode 编号对应的字符。由于固定占用两个字节,char 只能表示 Unicode 编号在 65536 以内的字符,而不能表示超出范围的字符。那超出范围的字符怎么表示呢?使用两个 char。
1 | // 将输出汉字 𠮷 |
*字符
在 Java 中,为了表示一些特殊字符,前面要加上反斜杠(\),这称为字符转义。
特殊字符
\u3000
表示一个中文空格。 ‘A’ 字符也可以用 Unicode 编码 ‘\u0041’ 表示。
char 的赋值形式:
1 | // 赋值的时候是按当前的编码解读方式,将这个字符形式对应的 Unicode 编号值赋给变量 |
char 的加减运算
按其 Unicode 编号进行运算,一般对字符做加减运算没什么意义,但 ASCII 码字符是有意义的。比如大小写转换,大写 0~9 的编号是 48~57,A~Z 的编号是 65~90,小写 a~z 的编号是 97~122,正好相差 32,所以大写转小写只需加 32,而小写转大写只需减 32。加减运算的另一个应用是加密和解密,将字符进行某种可逆的数学运算可以做加解密。
1 | // 字符 转 int 属于自动升位,不需要强转 |
布尔类型
在 Java 语言中声明布尔类型的关键字是 boolean,只有两个值:true 和 false。
变量
变量和常量是构成表达式的重要部分,变量所代表的内部是可以被修改的。
- 一定要注意变量属于哪个类型和它的取值范围。
- 强制类型转换(小能默认转大,大转小要用强转)。
- 强转可以取某个实数的整数部分(int a = (int)12.34)。
方法内局部变量(自动变量)
- 局部变量只定义在局部范围内,如:方法内,语句内等。
- 局部变量存在于栈内存中。
- 作用的范围结束,变量空间会自动释放。
- 局部变量没有默认初始化值。
- 在方法体内可以定义本方法所使用的变量,这种变量是局部变量,它的生存期与作用域是在本方法内。
- 方法体内定义变量时,变量前不能加修饰符
- 局部变量在使用前必须明确赋值,因为它没有默认值,否则编译时会出错。
- 在语句块中定义的变量它只在语句块中有效;
- 方法参数:作用域是整个方法。
- 异常处理参数: catch 跟随的异常处理块。
非静态成员变量
- 定义在类中,在整个类中都可以被访问。
- 成员变量随着对象的建立而建立,存在于对象所在的堆内存中。
- 成员变量有默认初始化值。
静态成员变量(全局变量/类变量/静态成员变量)
在定义 class 时,作为成员变量且加了 static 关键字。
常量
在 Java 中,常量是一种在程序运行期间其值不会改变的变量。通常用来表示固定的、不可变的数据。
常量可以是整数、浮点数、字符、字符串等数据类型。为了表明一个变量是常量,需要在变量声明时使用 final
关键字。例如:
1 | final int MAX_COUNT = 100; |
在上面的例子中,MAX_COUNT
就是一个常量,它的值被设定为 100,并且在程序运行过程中不能被修改。
常量的使用可以提高代码的可读性和可维护性,因为它们清晰地表明了一些固定的值,而且在需要更改这些值时也更容易进行管理。
字面量
字面量是指在编程语言中直接表示值的表达式。它是一个固定的值,不需要计算或解析。
在 Java 中,字面量可以是各种数据类型的具体值,比如整数字面量(如 123)、浮点数字面量(如 3.14)、字符字面量(如 ‘A’)、字符串字面量(如 “Hello, World!”)等。
数值类型相互转换
自动类型转换
自动类型转换就是需要类型之间转换是自动的,不需要采取其他手段,总的原则是小范围数据类型可以自动转换为大范围数据类型,列类型转换顺序如图所示,从左到右是自动。
注意 如图所示,char 类型比较特殊,char 自动转换为 int、long、float 和 double,但 byte 和 short 不能自动转换为 char,而且 char 也不能自动转换为 byte 或 short。
强制类型转换
在数值类型转换过程中,除了需要自动类型转换外,有时还需要强制类型转换,强制类型转换是在变量或常量之前加上“(目标类型)”实现。
参考
- 丁振凡编著,《Java 语言程序设计(第 2 版)》华东交大版,2014.9
- 免费公开课_传智播客和黑马程序员免费公开课 http://yun.itheima.com/open
- Java 从小白到大牛-图书-图灵社区 http://www.ituring.com.cn/book/2480