Java 核心技术面试精讲
杨晓峰
前 Oracle 首席工程师
125942 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
Java 核心技术面试精讲
15
15
1.0x
00:00/00:00
登录|注册

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

默认缓存范围是-128到127
Java原始数据类型和引用类型的局限性
原始数据类型的线程安全
包装类是不可变类型
Integer缓存范围可调整
建议避免无意中的装箱、拆箱行为
缓存机制存在于其他包装类
语法糖
使用静态工厂方法valueOf
发生在编译阶段
计算或获取Java对象的大小
对象的内存结构
源码分析
理解自动装箱、拆箱
Integer源码分析
原始数据类型和包装类的差异
自动装箱时缓存机制是否起作用
自动装箱/自动拆箱发生阶段
自动装箱和自动拆箱功能
提供数学运算、转换等操作
int类型字段存储数据
long
double
float
int
char
short
byte
boolean
一课一练
知识扩展
考点分析
Integer包装类
Java原始数据类型
int和Integer有什么区别?

该思维导图由 AI 生成,仅供参考

Java 虽然号称是面向对象的语言,但是原始数据类型仍然是重要的组成元素,所以在面试中,经常考察原始数据类型和包装类等 Java 语言特性。
今天我要问你的问题是,int 和 Integer 有什么区别?谈谈 Integer 的值缓存范围。

典型回答

int 是我们常说的整形数字,是 Java 的 8 个原始数据类型(Primitive Types,boolean、byte 、short、char、int、float、double、long)之一。Java 语言虽然号称一切都是对象,但原始数据类型是例外。
Integer 是 int 对应的包装类,它有一个 int 类型的字段存储数据,并且提供了基本操作,比如数学运算、int 和字符串之间转换等。在 Java 5 中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java 可以根据上下文,自动进行转换,极大地简化了相关编程。
关于 Integer 的值缓存,这涉及 Java 5 中另一个改进。构建 Integer 对象的传统方式是直接调用构造器,直接 new 一个对象。但是根据实践,我们发现大部分数据操作都是集中在有限的、较小的数值范围,因而,在 Java 5 中新增了静态工厂方法 valueOf,在调用它的时候会利用一个缓存机制,带来了明显的性能改进。按照 Javadoc,这个值默认缓存是 -128 到 127 之间。

考点分析

今天这个问题涵盖了 Java 里的两个基础要素:原始数据类型、包装类。谈到这里,就可以非常自然地扩展到自动装箱、自动拆箱机制,进而考察封装类的一些设计和实践。坦白说,理解基本原理和用法已经足够日常工作需求了,但是要落实到具体场景,还是有很多问题需要仔细思考才能确定。
面试官可以结合其他方面,来考察面试者的掌握程度和思考逻辑,比如:
我在专栏第 1 讲中介绍的 Java 使用的不同阶段:编译阶段、运行时,自动装箱 / 自动拆箱是发生在什么阶段?
我在前面提到使用静态工厂方法 valueOf 会使用到缓存机制,那么自动装箱的时候,缓存机制起作用吗?
为什么我们需要原始数据类型,Java 的对象似乎也很高效,应用中具体会产生哪些差异?
阅读过 Integer 源码吗?分析下类或某些方法的设计要点。
似乎有太多内容可以探讨,我们一起来分析一下。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java中的int和Integer虽然在表面上看起来很相似,但实际上有着明显的区别。int是Java的原始数据类型之一,代表整数,而Integer是int的包装类,它提供了对int类型数据的封装和操作。在Java 5中引入了自动装箱和自动拆箱功能,使得int和Integer之间的转换更加便捷。另外,Java 5还新增了静态工厂方法valueOf,利用缓存机制来提升性能,其中默认缓存范围是-128到127之间的数值。这篇文章涵盖了Java中的原始数据类型和包装类的基础知识,以及自动装箱、自动拆箱机制和缓存机制的相关内容。在面试中,这些知识点可能会成为考察的重点,面试官可能会结合其他方面来考察面试者的掌握程度和思考逻辑。文章还提出了一些可能的面试问题,如自动装箱/自动拆箱发生的阶段、缓存机制的作用、原始数据类型和包装类的差异以及Integer源码的设计要点等。因此,这篇文章对于想要快速了解Java中int和Integer的区别以及相关面试考点的读者来说是一份有价值的资料。文章还涵盖了自动装箱、拆箱的语法糖、源码分析、原始类型线程安全以及Java原始数据类型和引用类型的局限性等内容,为读者提供了全面的技术视角。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(82)

  • 最新
  • 精选
  • Kyle
    置顶
    节选自《深入理解JAVA虚拟机》: 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。 HotSpot虚拟机的对象头包括两部分信息,第一部分用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为"Mark Word"。 对象头的另外一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身,这点将在2.3.3节讨论。另外,如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中却无法确定数组的大小。 接下来的实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。 第三部分对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。
    2018-05-19
    2
    139
  • cookie。
    置顶
    对象由三部分组成,对象头,对象实例,对齐填充。 其中对象头一般是十六个字节,包括两部分,第一部分有哈希码,锁状态标志,线程持有的锁,偏向线程id,gc分代年龄等。第二部分是类型指针,也就是对象指向它的类元数据指针,可以理解,对象指向它的类。 对象实例就是对象存储的真正有效信息,也是程序中定义各种类型的字段包括父类继承的和子类定义的,这部分的存储顺序会被虚拟机和代码中定义的顺序影响(这里问一下,这个被虚拟机影响是不是就是重排序??如果是的话,我知道的volatile定义的变量不会被重排序应该就是这里不会受虚拟机影响吧??)。 第三部分对齐填充只是一个类似占位符的作用,因为内存的使用都会被填充为八字节的倍数。 还是个初学者。以上是我了解,不知道有没有错,希望老师能告知。
    2018-05-19
    13
    195
  • 行者
    1. Mark Word:标记位 4字节,类似轻量级锁标记位,偏向锁标记位等。 2. Class对象指针:4字节,指向对象对应class对象的内存地址。 3. 对象实际数据:对象所有成员变量。 4. 对齐:对齐填充字节,按照8个字节填充。 Integer占用内存大小,4+4+4+4=16字节。

    作者回复: 不错,如果是64位不用压缩指针,对象头会变大,还可能有对齐开销

    2018-05-20
    3
    41
  • George
    计算对象大小可通过dump内存之后用memory analyze分析

    作者回复: 嗯,也可以利用: jol,jmap,或者instrument api(Java agent)等等

    2018-05-25
    18
  • Gerald
    为什么我感觉都这么难啊😭

    作者回复: 感谢反馈,具体哪个方面,我可以调整一下,尽量照顾不同基础的朋友

    2018-05-29
    5
    15
  • Miaozhe
    杨老师,问个问题,如果使用原始类型int定义一个变量在-128和127之间,如int c = 64;会放入Integer 常量缓存吗(IntegerCache)?编译器是怎么操作的?

    作者回复: 不需要,不是对象

    2018-05-21
    8
  • 云泥
    缓存的原理是怎样的?感觉这部分还没理解

    作者回复: 建议你跟踪下类似Integer.valueOf(xxx),看看IntegerCache的实现,底层是个常量数组,在静态初始化块中创建并缓存对象

    2019-01-27
    2
    5
  • 云飞
    想知道Integer 不就是4字节嘛?为什么要从对象角度考虑就变成了4+4+4+4=16字节?

    作者回复: header 补齐,如果仅仅是表示数据,object是个高成本的东西,而且开销不仅是空间,引用结构也会影响内存布局

    2018-10-15
    2
  • Darren
    老师,原始数据类型的包装类是对象吗?

    作者回复: 类是类,实例化后才是对象

    2018-06-16
    2
  • 小浪
    那么请问杨老师,什么时候用基本类型,什么时候用包装类?

    作者回复: 看应用场景的需求吧,在程序可读性、开发效率和性能等方面进行取舍,包装类毕竟创建的是对象,有很多方便的方法,甚至有些场合,例如一些Collection,还只接受对象

    2019-02-10
    1
收起评论
显示
设置
留言
82
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部