Java核心 -- int + Integer
包装类
- Integer是int对应的包装类,里面有一个int类型的字段存储数据,并提供了基本的操作
- 在Java 5,引入了自动装箱和自动拆箱(boxing/unboxing),Java可以根据上下文,自动进行转换
- 在Java 5,还引入了值缓存(静态工厂方法valueOf),默认缓存范围为**-128 ~ 127**
- Boolean,缓存Boolean.TRUE/Boolean.FALSE
- Short,缓存**-128 ~ 127**
- Byte,数值有限,全部缓存
- Character,缓存\u0000 ~ \u007F
自动装箱 + 自动拆箱
1 | Integer integer = 1; |
1 | 1: invokestatic // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; |
- 自动装箱和自动拆箱是一种语法糖,发生在编译阶段(生成一致的字节码)
- javac自动把装箱转换为Integer.valueOf(可以利用值缓存机制),把拆箱转换为Integer.intValue
- 在性能敏感的场合,要尽量避免无意中的自动装箱和自动拆箱;但在大多数产品代码里,还是以开发效率优先
线程安全的计数器
原子类实现
1 | // 简单明了 |
原始类型实现
1 | // 复杂 |
不变类
1 | private final int value; |
BYTES
1 | // Integer |
原始类型的线程安全
- 原始类型的变量,需要使用并发相关手段,才能保证线程安全
- 如果有线程安全的计算需要,优先考虑AtomicInteger、AtomicLong等线程安全类
- 部分比较宽的数据类型,如float、double,都不能保证更新操作的原子性(可能读到只更新了一半数据位的数值)
局限性
- 原始类型与Java泛型不能配合使用
- Java的泛型是伪泛型,属于编译期的技巧(_类型擦除+强制转换_)
- 原始类型无法转换为Object,因此无法与泛型配合使用
- 无法高效表达数据
- 原始类型数组,在内存里是一段连续的内存
- 引用类型数组,存储的是引用,实际的对象分散在堆里,导致低效的数据操作,也无法充分利用CPU缓存
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.