数据类型

数据类型分为基本类型和对象类型。

1. 基本类型

Java 中的基本类型有 8 种,其中有 4 种整型、2 种浮点型、char 和 boolean。还有 void 和 reference 类型

  1. 基本类型值存储在内存栈上。
  2. 基本类型所占空间大小固定。
  3. 所有数值类型都有正负号。

1.1 整型

类型 包装类 存储需求 取值范围 零值 备注
long Long 8 字节 64 bits -2^63 ~ +2^63-1 0L 后缀加L或l
int Integer 4 字节 32 bits -2^31 ~ +2^31-1 0 最常用,范围超20亿
short Short 2 字节 16 bits -2^15 ~ +2^15-1 (short)0 控制占用存储空间的大数组
byte Byte 1 字节 8 bits -2^7 ~ +2^7-1 (byte)0 底层文件处理
  1. 十六进制前缀 0x 或0X
  2. 八进制前缀 0
  3. 二进制前缀 0b 或 0B(Java 7 开始)
  4. 数字加下划线更易读,如 1_000_000,编译器会去掉(Java 7 开始)
  5. 没有后缀标识的整数默认为 int 类型

1.2 浮点

类型 包装类 存储需求 取值范围 零值 备注
double Double 8 字节 64 bits 大约-2^1024 ~ -2^-1074 —— 0 —— 2^-1074 ~ 2^1024(有效 15 位) 0.0d 后缀 D 或 d,最常用。
float Float 4 字节 32 bits 大约-2^128 ~ -2^-149 —— 0 —— 2^-149 ~ 2^128(有效 6~7 位) 0.0f 后缀 F 或 f,单精度库或大量数据
  1. 没有后缀F的浮点数默认是 double
  2. 浮点数不能绝对精确,因为二进制种无法精确表示 1/10,不允许误差应使用 BigDecimal 类。

浮点数的结构与整型不同,指数的底数为 2,尾数表示小数部分

类型 符号位(S) 指数位(E) 尾数位(M)
float 1 bit 8 bits 23 bits
double 1 bit 11 bits 52 bits

1.3 字符

类型 包装类 存储需求 取值范围 零值 备注
char Character 2 字节 16 bits int0-2^16-1 ,hex’\u0000’~’’\Uffff’ ‘\u0000’ char 字面量要用单引号括起来。
  • 转移序列 \u 可以出现在加引号的字符常量或字符串外(其它所有转义序列不可以)
  • 警告:Unicode 转移序列会在解析代码前得到处理
  • 警告:当心注释里的 \u,如“\u00A0”换行符,或“c:\user”,语法错误,因为没跟 4 个十六进制数
  • 解决方案:字符串中用转义符“\”来去除“\u”造成的不必要影响

1.4 布尔

boolean 只有两个值:true、false,可以使用 1 bit 来存储,但是具体大小没有明确规定。

JVM 会在编译时期将 boolean 类型的数据转换为 int,使用 1 来表示 true,0 表示 false。

JVM 支持 boolean 数组,但是是通过读写 byte 数组来实现的。

整型和布尔之间不能转换,不能用 0 当作 false,可以使用条件表达式

1.5 类型转换

不要强制转换 boolean 类型,可用条件表达式

自动类型转换图示:byte -> short(char) -> int -> long -> float -> double ,强制类型与之相反

1)自动类型转换

运算或方法调用时,系统会将较小的数据类型自动转换为较大的数据类型

  • 当使用 +、-、*、/、% 运算符对基本类型进行运算时,转换为较大的数据类型,如最大的小于 int,则转为 int
2)强制类型转换

强制类型将较大的数据类型转化为较小的数据类型,可能导致精度损失。

  • 当使用 +=、-=、*=、/=、%= 运算符对基本类型进行运算时,运算符右边的数值将首先被强制转换成与运算符左边数值相同的类型,然后再执行运算,且运算结果与运算符左边数值类型相同。

2. 包装类型

  • 所有的基本类型都有一个与之对应的类。包装类都是声明为 final的,不可变,不可被继承。
  • 对象引用存储在内存栈上,而对象本身的值存储在内存堆上。
  • 对一个对象进行操作时,我们真正操作的是它的句柄。
  • 自动装箱:基本类型自动转换成包装类,调用了 Integer.valueOf()
  • 自动拆箱:包装类自动转换为基本类型,调用了 X.intValue()

2.1 大数值

  • BigInteger 支持任意精度的整数。
  • BigDecimal 支持任意精度的浮点数字。
  • 转换方法: valueOf
  • 运算方法: add, multiply, divide 等

3. 缓存池

基本类型对应的缓冲池如下:

  • boolean:true, false
  • byte、short、int、long:-128 ~ 127
  • char:\u0000 ~ \u007F

在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。

3.1 IntegerCache

Integer 缓冲池 IntegerCache, 是静态类,上界可以通过参数调整。

加载的时候会初始化一个 int 数组,填上 -128 ~ 127 的值。

3.2 valueOf() 方法

valueOf() 方法会使用缓存池中的对象,多次调用会取得同一个对象的引用。

编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。

Author: iMine
Link: https://imine141.github.io/2020/08/15/Java%E5%9F%BA%E7%A1%80/%E5%9F%BA%E7%A1%80%E8%AE%BE%E8%AE%A1/%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.