第7讲 | int和Integer有什么区别?

2019-04-18  本文已影响0人  governlee

典型回答

Java 语言虽然号称一切都是对象,但原始数据类型是例外。
Java 的 8 个原始数据类型(Primitive Types,boolean、byte 、short、char、int、float、double、long)之一。

Integer 是 int 对应的包装类,它有一个 int 类型的字段存储数据,并且提供了基本操作,比如数学运算 ,int和字符串之间的转换等。

自动装箱和自动拆箱(boxing/unboxing): 根据上下文,自动进行转换,极大地简化了相关编程。

Integer 的值缓存:大部分数据操作都是集中在有限的、较小的数值范围。调用它的时候会利用一个缓存机制,带来了明显的性能改进。这个值默认缓存是 -128 到 127 之间

理解自动装箱、拆箱

自动装箱实际上算是一种语法糖。什么是语法糖?可以简单理解为 Java 平台为我们自动进行了一些转换,保证不同的写法在运行时等价,它们发生在编译阶段,也就是生成的字节码是一致的。

javac 替我们自动把装箱转换为 Integer.valueOf(),把拆箱替换为 Integer.intValue()。

这种缓存机制并不是只有 Integer 才有,同样存在于其他包装类:

建议避免无意中的装箱、拆箱行为,尤其是在性能敏感的场合。

使用原始数据类型、数组甚至本地代码实现等,在性能极度敏感的场景往往具有比较大的优势,用其替换掉包装类、动态数组(如 ArrayList)等可以作为性能优化的备选项。

源码分析

Integer 的缓存范围虽然默认是 -128 到 127,缓存上限值实际是可以根据需要调整的,JVM 提供了参数设置:

-XX:AutoBoxCacheMax=N

包装类的值是不可变的,都被声明为“private final”。

Integer 等包装类,定义了类似 SIZE 或者 BYTES这样的常量,代表数据类型存储的bits和bytes。不管是 32 位还是 64 位环境,开发者无需担心数据的位数差异。

原始类型线程安全

原始数据类型的变量,要使用并发相关手段,才能保证线程安全。建议使用AtomicInteger、AtomicLong 这样的线程安全类。

部分比较宽的数据类型,比如 float、double,甚至不能保证更新操作的原子性,可能出现程序读取到只更新了一半数据位的数值。

Java 原始数据类型和引用类型局限性

上一篇 下一篇

猜你喜欢

热点阅读