前言
今天的LeetCode是一道困难级别的题目(1473 粉刷房子 III ),虽然是以往训练的动态规划。在看了题解之后,理解了思路,但是看代码,选择放弃。。。用一个三维数组来处理的。。
所以选择把基础打牢
基本数据类型
基本数据类型存储在栈中,而封装数据类型存储在堆中。
数值类型
- byte 1字节 Byte
- short 2字节 Short
- int 4字节 Integer
- long 8字节 Long
浮点型
- float 4字节 Float
- double 8字节 Double
字符类型
- char 2字节 Character
一个中文字符占多少个字节,由编码决定。Java默认ISO-8859-1(个人理解,是对Unicode编码的扩充),占2个字节,而GBK/GB2312同样占用2个字节。UTF8编码则占用3个字节。
布尔型
- boolean 1字节 Boolean
自动类型转换
java语言规定:当一个算术表达式中包含多种基本数据类型的值时,整个算术表达式将自动提升。
转换规则
- byte/char/short -> int -> long -> float -> double
整型与浮点型的互相转换会存在精度丢失 - 在运算时,精度低的会自动向精度高的转换。直到数据类型达到运算中最高精度的类型。
- 特殊:byte/char/short只要参与运算,都会先被转成int,哪怕是byte+byte。
- 特殊运算符
4.1 复合运算符,例如: +=,/=, %=
包含隐式转换,例如:a += 1,等价于 a = (a的类型) a + 1;
4.2 赋值运算
允许直接将int赋值给byte/char/short,但不允许其他高精度赋值给低精度(需要强制转换才行)。
自动装箱
自动装箱是将基本数据类型封装成对象的过程
例如:Integer a = 123;
通过javap命令,可以看到该语句被编译后,通过Integer.valueOf()方法来自动装箱了。
0: bipush 123
2: invokestatic #11 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
类似的,其他基本数据类型也有类似方法:Boolean/Byte/Char/Short/Long/Float/Double。而这就是自动装箱的奥秘。
自动拆箱
与自动装箱相对,自动拆箱是其反向过程:将封装类型转换成基本类型
例如:int a = Integer.valueOf(123);
反编译之后
6: bipush 123
8: invokestatic #11 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: invokevirtual #15 // Method java/lang/Integer.intValue:()I
14: istore_2
可以看出,自动拆箱是通过Integer.intValue()方法来实现
同样的,其他基本数据类型也有类似方法:Boolean/Byte/Char/Short/Long/Float/Double
封装类型的缓存池
对于可以用整数来表示的类型,Java都会有一个XxxCache类来缓存常用的封装类型。
而缓存是通过数组来是实现的,而咱们对象头的数组长度是用4个字节表示的,所以最大的数组长度就是Integer.MAX_VALUE.
- Byte :缓存 -128~127,也就是全部可表示的数值范围了
- Charactor: 缓存 0~127,但是注意,这个是对应的符号的Unicode值
- Short: 缓存-128~127
- Integer: 默认缓存 -128~127,可通过java.lang.Integer.IntegerCache.high来改变缓存的最大值。如果小于127,则缓存到127.但最大不能超过数组长度限制,也就是Integer.MAX_VALUE - 129(-128 ~ 0)
- Long: 缓存-128~127
- Boolean:TRUE,FALSE
在这些类型的自动装箱过程中,valueOf方法,会优先从缓存中取对象,所以在判断以上类型的是否相同/相等时要注意咯。
而浮点型没有缓存,都是直接调用构造方法创建的。
本文深入探讨了Java中的基本数据类型及其内存存储,包括自动类型转换和特殊的运算规则。同时,详细解析了自动装箱和拆箱的过程,以及封装类型缓存池的工作原理,特别是Integer对象的缓存范围。此外,还提到了不同数据类型的大小和在运算中的精度问题。
2万+

被折叠的 条评论
为什么被折叠?



