Java中一共有8中基本数据类型
4种整形,:byte、short、int、long
- byte:长度为1字节8位(bit),取值10000000(-128)到 01111111(127),变量默认初始值为0,包装类为Byte
- short:长度为2字节16位(bit),取值1000 0000 0000 0000(-32768)到 0111 1111 1111 1111(32767),变量默认初始值为0,包装类Short
- int:长度为4字节32位(bit),取值-2^31 (-2,147,483,648)到 2^31-1(2,147,483,647),变量默认初始值为0,包装类Integer
- long:长度为8字节64位(bit),取值-2^63 (-9,223,372,036,854,775,808)到 2^63-1(9,223,372,036,854,775,8087),变量默认初始值为0或0L,包装类Long
2种浮点型:float、double
- float:长度为4字节32位(bit),变量初始化默认值0.0f,包装类Float
- double:长度为8字节64位(bit),变量初始化默认值0.0d,包装类Double
1种字符型:char
- char:占2字节16bit,可以赋值单字符以及整型数值, 变量初始化无默认值,包装类Character。
1种布尔型:boolean
- boolean:仅有两个值true, false,变量初始化默认值false,包装类Boolean。
Java类型分类
- 基本类型:在JVM栈中分配空间存值
- 引用类型:在堆中分配空间存值
void类型
- void的包装类为Void,不能被继承,不能被new。
为什么需要包装类
- Java是一种面向对象的编程语言,有时候需要使用对象,而不是基本数据类型,比如集合类,不能存放基本数据类型。为了让基本数据类型具有对象的特性,就出现了包装类。
装箱与拆箱
- 装箱:把基本类型转换成包装类型的过程就是装箱。
- 拆箱:把包装类型转换成基本类型的过程就是拆箱。
自动拆装箱
在javaSE5中,为了减少开放人员的工作,提供了自动拆装箱功能。
- 自动装箱:将基本类型自动转换成对应的包装类
- 自动拆箱:将包装类自动转换成对应的基本类型
自动拆装箱的实现原理
- 自动装箱都是通过包装类的valueOf方法实现的
- 自动拆箱都是通过包装类对象xxxValue方法实现的,比如intValue
自动拆装箱使用场景
- 将基本数据类型放入集合类:集合类中存放的都是对象类型,当我们add(基本数据类型)时,不会报错,因为java会帮我们自动装箱
- 包装类和基本数据类型比较大小:会先将包装类进行拆箱成基本数据类型,再进行比较
- 包装类型进行运算:会先将包装类拆装成基本数据类型,再进行运算
- 三目运算符的使用:flag ? i : j
函数参数与返回值
//自动拆箱 public int getNum1(Integer num) { return num; } //自动装箱 public Integer getNum2(int num) { return num; }
自动拆装箱与缓存
在Java SE5中,Integer操作引入了新功能来节省内存和提高性能
- 适用于整数区间-128~+127
- 只适用于自动装箱,使用构造函数创建对象不适用
- 只适用于整形,浮点型不行
public class Test {
public static void main(String[] args) {
//不创建对象且在-128~127中
Integer a = 1;
Integer b = 1;
System.out.println(a == b);//true
//创建对象且在-128~127中
Integer c = new Integer(1);
Integer d = new Integer(1);
System.out.println(c == d);//fasle
//不创建对象且不在-128~127中
Integer e = 200;
Integer f = 200;
System.out.println(e == f);//false
}
}自动拆装箱带来的问题
- 包装对象之间的数值比较不能简单的使用==,除了特殊情况(如Integer的-128~127),其他比较都需要使用equals比较
- 如果包装类对象为NULL,那么自动拆箱就可能会抛出NPE
- 如果一个for循环中有大量拆装箱操作,会浪费很多资源
延伸
为什么4.0 - 3.6 = 0.40000001?
因为浮点数值是采用二进制表示的,而二进制无法精确地表示分数1/10,因为10不能用2的几次方来表示