int和Integer有什么区别?-《Java核心技术》

  1. 自动装箱、拆箱

Integer是int对应的包装类,有一个int类型的字段存储数据,并且提供了基本操作,比如数字运算、int和字符串之间的转换等。java5后引入了自动装箱和拆箱功能。

java5中新增的valueOf可以在调用时使用缓存机制,默认是-128~127,可以通过-XX:AutoBoxCacheMax=N调整缓存机制也存在与Boolean、Short(-128~127)、Byte(全部缓存)、Character('\u0000'到'\u007F')。自动装/拆箱使用的也是valueOf,所以可以利用缓存。

原则上建议避免无意中的装箱、拆箱行为

使用原始数据类型在性能极度敏感的场景往往具有比较大的优势。

  1. 源码分析

不仅String不可变,Integer和Boolean也是不可变的。

Integer等包装类,对于SIZE、BYTES等常量,在不同位数的JDK上表现一致。

  1. 原始数据类型安全

原始数据类型在多线程情况下建议考虑使用类似AtomicInteger、AtomicLong这样的线程安全类。部分比较宽的数据类型,比如float、double甚至不能啊播种更新操作的原子性,可能出现程序读取到只更新了一半数据位的数值。

  1. java原始数据类型和引用类型局限性

原始数据类不能和java泛型配合使。

对象无法高效表达数据,也不便于表达复杂的数据结构,比如vector和tuple。原始数据类型数组是一段连续内存,但是对象都是引用,对象数组中的对象分散的存储在堆的不同位置,无法充分利用现代CPU缓存机制。

  1. 对象包括哪些部分?

包括对象头、对象实例和对齐填充。

其中对象头一般是十六个字节,包括两部分:第一部分存储对象自身的运行时数据,包括哈希码、GC年代、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,第二个部分是类型指针,对象指向它的类元数据指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

对象实例是对象真正存储的有效信息,包括父类继承下来和类自己定义的,这部分存储顺序会被虚拟机和代码中定义的顺序影响。

第三部分对齐是一个类似占位符的作用,因为内存的使用都会被填充为八字节的倍数。

  1. 思路:

原始数据类型和java泛型不能配合使用(java的泛型实际上是一种违泛型,完全是一种编译期的技巧,java编译期会自动将类型转换为对应的特定类型,所以使用泛型,必须保证相应类型可以转换为Object)。所以诞生了auto-boxing/unboxing机制,把原始数据类型包装为Object为父类的类型,这样就不需要使用者手动显式转换。但是使用类在计算密集型的程序中不友好,原始数据类型在内存中存的是值,找到位置便可获得值。类类型在内存在保存的是引用,需要更多IO。所以开发者要做计算则用原始数据类型,要更抽象解决业务问题则用类类型。最后,为了弥补object计算能力的不足,还涉及了static valueOf()方法提供缓存机制。

comments powered by Disqus