目录
1 基本类型
Java里面只有八种原始类型,其列表如下:
- 实数:double、float
- 整数:byte、short、int、long
- 字符:char
- 布尔值:boolean
复杂类型和基本类型的内存模型本质上是不一样的,简单数据类型的存储原理是这样的:简单数据类型不存在“引用”的概念,都是直接存储在内存栈上,数据本身的值就是存储在栈空间里面,而Java语言里面只有这八种数据类型是这种存储模型;而其他的只要是继承于Object类的复杂数据类型都是按照Java里面存储对象的内存模型来进行数据存储的。“引用”是存储在有序的内存栈上的,而对象本身的值存储在内存堆上的。
Java的简单数据讲解列表如下:
int:用4个字节存储,范围为-2,147,483,648到2,147,483,647,在变量初始化时默认值为0。(2^33-1)
short:用2个字节存储,范围为-32,768到32,767 (2的16次方),初始化时默认值为0
long:用8个字节存储,范围为正负2的64次方,在变量初始化的时候,默认值为0L或0l
byte:用1个字节存储,范围为-128到127,在变量初始化时默认值也为0。
float:用4个字节存储,范围为32位IEEEE 754单精度范围,默认值为0.0f或0.0F,在初始化的时候可以写0.0。
double:用8个字来存储,范围为64位IEEE 754双精度范围,默认值为0.0。
char:用2个字节存储,因为Java本身的字符集不是用ASCII码来进行存储,是使用的16位Unicode字符集,它的字符范围即是Unicode的字符范围,在变量初始化的时候,char类型的默认值为'u0000'。
boolean:在存储的时候不使用字节,仅仅使用1位来存储,范围仅仅为0和1,其字面量为true和false,默认值为false。
2 基本类型的包装类
原始类型 包装类:
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
2.1 基本类型与包装类型区别与关联
- 存储模式:基本类型存储在栈,不存在“引用”,包装类型拥有引用和对象本身:引用存储在栈,而对象本身存储在堆上
- 初始值:基本类有不同的初始值,而包装类型默认是null
- 基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成
2.2 装箱与拆箱
Integer x = 2; // 装箱 基本类型变包装类型
int y = x; // 拆箱 包装类型变基本类型
2.3 缓冲池
重点:缓冲池的存在
- 跟String一样拥有缓冲池的基本类型:boolean、byte、short、int、char
- new Integer(123) 与 Integer.valueOf(123) 的区别在于:
- new Integer(123) 每次都会新建一个对象
- Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。
注意以下判断:
Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x == y); // false
Integer z = Integer.valueOf(123);
Integer k = Integer.valueOf(123);
System.out.println(z == k); // true
valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
- 在 Java 8 中,Integer 缓存池的大小默认为 -128~127。
编译器会在缓冲池范围内的基本类型自动装箱过程调用 valueOf() 方法
因此多个 Integer 实例使用自动装箱来创建并且值相同,那么就会引用相同的对象。
!!!!注意以下判断:
Integer m = 123;
Integer n = 123;
System.out.println(m == n); // true
如果在缓冲池之外:
Integer m = 323;
Integer n = 323;
System.out.println(m == n); // false
3 隐式类型转换
结论:只能低精度向高精度转换,反则不行。
例如:short可以转为int,但int不能作为short;同理float和double;
例子一
float f = 1.1f;//正确
float f = 1.1;//错误
double=1.1;//正确
分析:
- 1.1 属于double类型,不能直接赋值给float变量,因为这是向下转型。Java 不能隐式执行向下转型,因为这会使得精度降低。
- 1f 才是float类型。
例子二:short s1 = 1; s1 = s1 + 1;
错! s1 + 1,s1是short类型,1是int型,s1会自动转换为int型的1,与1相加后,得到int型的2,因此不能赋值给short,应该加上强制转换:s1 = (short) (s1 + 1);
例子三:short s1 = 1; s1 += 1;
正确! 执行s1+=1;其实执行的是s1 = (short) (s1 + 1); 其中会有一个强制转换的过程
例子四:short s1=1,s2=1;short s3=s1+s2;
错误!这里是编译器从数据安全方面考虑,如果s1和s2都是较大的short类型数,可能会导致溢出,所以会要求强制转换到int。正确写法:short s3 = (int)(s1 + s2);
java中byte,short,char在进行计算时候都会提升为int类型
4 switch
- switch支持char, byte, short, int, Character, Byte, Short, Integer, String, or an enum
- switch不支持long,是因为switch的设计初衷是对那些只有少数的几个值进行等值判断