int和Integer有什么区别?

《Java核心技术面试精讲–杨晓峰》学习笔记目录

文章目录

      • 正文
        • 简单的区分
        • 自动装箱 / 自动拆箱
        • 原始数据类型
        • 包装类
      • 补充
        • 为什么一个字节的范围是-128~127,而不是-127~127?
        • Java 对象要比原始数据类型开销大的多。你知道对象的内存结构是什么样的吗?比如,对象头的结构。如何计算或者获取某个 Java 对象的大小?

正文

简单的区分

  • int是基本数据类型,其他基本数据类型为:int short long float double char byte boolean
  • Integerint对应的包装类,它有一个int类型的字段存储数据,并且提供了基本操作,比如数学运算、int和字符串之间转换等。
  • Java 5 中引入了自动装箱和自动拆箱功能,原始数据类型和包装类会自动转换。

自动装箱 / 自动拆箱

  • 语法糖:简单理解为 Java 平台为我们自动进行了一些转换,保证不同的写法在运行时等价,它们发生在编译阶段,也就是生成的字节码是一致的。
  • 自动装箱 / 自动拆箱算是一种语法糖,发生在编译器。比如 intIntegerjavac替我们自动把装箱转换为Integer.valueOf(),把拆箱替换为Integer.intValue()valueOf背后实现是将int值为-128127之间的Integer对象进行缓存,在调用时候直接从缓存中获取,进而提升构建对象的性能
  • 注意:建议避免无意中的装箱、拆箱行为 。创建一个对象比创建一个基本数据类型所消耗的内存大许多。

原始数据类型

  1. 基本类型均具有取值范围,在大数*大数的时候,有可能会出现越界的情况。
  2. 基本类型转换时,使用声明的方式。例:long result= 1234567890 * 24 * 365;结果值一定不会是你所期望的那个值,因为
    . 1234567890 * 24已经超过了int的范围,如果修改为:long result= 1234567890L * 24 * 365;就正常了。
  3. 慎用基本类型处理货币存储。如采用double常会带来差距,常采用BigDecimal、整型(如果要精确表示分,可将值扩大100倍转化为整型)解决该问题。
  4. 优先使用基本类型。原则上,建议避免无意中的装箱、拆箱行为,尤其是在性能敏感的场合,
  5. 如果有线程安全的计算需要,建议考虑使用类型AtomicInteger、AtomicLong 这样的线程安全类。部分比较宽的基本数据类型,比如float、double,甚至不能保证更新操作的原子性,可能出现程序读取到只更新了一半数据位的数值。
  6. 基本数据类型是有默认值的,而对象数据类型没有默认值。比如从数据库中查询用户年龄,如果用户并没有设置年龄信息,数据库中代表年龄的列age =null ,那么在使用基本数据类型接收年龄值的时候就无法区分用户是年龄为0还是未设置年龄的情况。

包装类

  • 包装类同样是 Immutable 类,可类比 String
  • Integer 等包装类,定义了类似 SIZE 或者 BYTES 这样的常量,因此不用考虑不同位数环境的差异

补充

为什么一个字节的范围是-128~127,而不是-127~127?

因为一个带符号数和一个不带符号数一样,8位能表示256个值,如果是-127~127的话,只有255个数!那还少一个。7位可以表示128个数,那加上正负肯定能表示256个不同的数。负数的补码等于其反码+1

Java 对象要比原始数据类型开销大的多。你知道对象的内存结构是什么样的吗?比如,对象头的结构。如何计算或者获取某个 Java 对象的大小?

对象由三部分组成,对象头,对象实例,对齐填充。

其中对象头一般是十六个字节,包括两部分,第一部分有哈希码,锁状态标志,线程持有的锁,偏向线程id,gc分代年龄等。第二部分是类型指针,也就是对象指向它的类元数据指针,可以理解,对象指向它的类。
对象实例就是对象存储的真正有效信息,也是程序中定义各种类型的字段包括父类继承的和子类定义的,这部分的存储顺序会被虚拟机和代码中定义的顺序影响。

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

对象头是由两部分组成,标记信息和类型指针

在64位平台上,两部分 分别占据 64位,即各8个字节,也就是一共 16字节,32位平台上对应减半。
但是对象指针占用64位来寻址一般来说是比较浪费的,所以 64位虚拟机上 可以开启压缩指针,用32位空间来寻址(可以寻址 32G的内存上限)
对应类型指针的占用就是 4字节了

所以,整个的对象头 就由 16字节 压缩到了 12字节。

你可能感兴趣的:(int和Integer有什么区别?)