为什么有基本数据类型了,还需要包装类?
● 基本数据类型之间的转换可以通过包装类来实现。
● Java是面向对象的语言,而基本数据类型不是对象类型。在一些场景中需要使用到对象类型,比如在集合中的元素就必须是对象类型。
缓存池
除了浮点数的包装类之外,其它包装类都有对应的缓存池或者缓存的设置。当基本数据类型在装箱时出于缓存池范围内,则会直接返回缓存中对应的包装类,而不是直接返回一个new出来的包装类。
这意味着缓存池范围内的基本数据类型,通过valueOf()获取的包装类对象一直都是同一个对象。
| 包装类 | 缓存池 | 缓存池大小 |
|---|---|---|
| Byte | ByteCache | -128~127 |
| Character | CharacterCache | (char)0~(char)127,即\u0000 ~ \u007F |
| Short | ShortCache | -128~127 |
| Integer | IntegerCache | 默认是-128~127,在jdk1.8种该最大值可以jvm启动参数-XX:AutoBoxCacheMax=<size>来指定 |
| Long | LongCache | -128~127 |
| Float | 无 | 无 |
| Double | 无 | 无 |
| Boolean | 直接定义了两个静态常量Boolean:TRUE和FALSE | Boolean.TRUE和Boolean.FALSE |
类型转换
类型转换分隐式转换和显式转换,其实就是自动类型转换和强制类型转换。
long、float、double变量的L、F、D尾缀
在声明long、float、double变量的时候,往往会在字面量末尾加上对应的L、F、D,也可以是小写的l、f、d,一般long变量尽量用大写的L,避免和数字的1和大写的i混淆。如下:
long a = 123L;
float b = 1.23F;
double c = 1.23D;Copy to clipboardErrorCopied
等号右边的数值叫做字面量literal,跟在字面量末尾的字母是为了告诉编译器数值的类型。有时候不添加尾缀,编译期也不会报错,因为整数型的字面量默认是int,浮点型的字面量默认是double,如下:
long a = 123;
double c = 1.23;Copy to clipboardErrorCopied
这里不会在编译期报错,是因为范围小的类型可以自动转换成范围大的类型,因为不会丢失精度,也叫向上转型。而float b = 1.23;会报错,是因为1.23默认是double类型,精度比float大,无法自动转换类型,需要进行强制类型转换,即float b = (float) 1.23;。
long的字节数是8,和float字节数一样,但是long b = 1.23f;还是会报错。这是因为long和float的存储方式不一样,尽管二者占据一样多的字节,但是float能表示的数值范围远超long,所以需要强制类型转换:long b = (long) 1.23f;。
既然不能直接将字面量赋值给精度更小的类型,那为什么byte b = 12; short s = 12;却不需要强制类型转换也不会报错?
这是因为编译器对整数型数值做了处理,对于整数字面量,如果赋值给比int范围更小的类型时(即byte/char/short类型),如果该字面量没有超出对应的赋值类型的范围,就会自动进行隐式类型转换。如果超出了范围,就会报错,需要经过强制类型转换才可以。
为什么byte b = 100不会报错,而int a = 100; byte b = a;却会报错?
前者是因为100属于byte的范围内,会隐式类型转换。后者的变量a已经被声明为int类型,将其直接赋值给byte变量需要经过强制类型转换:int a = 100; byte b = (byte) a;
short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
总结就是+=有隐式的强制类型转换。