Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >int和Integer有什么区别?

int和Integer有什么区别?

原创
作者头像
灬沙师弟
发布于 2022-10-07 08:59:16
发布于 2022-10-07 08:59:16
4.4K1
举报
文章被收录于专栏:Java面试教程Java面试教程

Java虽然号称是面向对象的语言,但是原始数据类型仍然是重要的组成元素,所以在面试中,经常考察原始数据类型和包装类等Java语言特性。

今天我要问你的问题是,int和Integer有什么区别?谈谈Integer的值缓存范围。

典型回答

int是我们常说的整形数字,是Java的8个原始数据类型(Primitive Types,boolean、byte 、short、char、int、foat、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源码吗?分析下类或某些方法的设计要点。

似乎有太多内容可以探讨,我们一起来分析一下。

知识扩展

1.理解自动装箱、拆箱

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

是一致的。

像前面提到的整数,javac替我们自动把装箱转换为Integer.valueOf(),把拆箱替换为Integer.intValue() ,这似乎这也顺道回答了另一个问题,既然调用的是Integer.valueOf,

自然能够得到缓存的好处啊。

如何程序化的验证上面的结论呢?

你可以写一段简单的程序包含下面两句代码,然后反编译一下。当然,这是一种从表现倒推的方法,大多数情况下,我们还是直接参考规范文档会更加可靠,毕竟软件承诺的是遵循

规范,而不是保持当前行为。

Integer integer = 1;

int unboxing = integer ++;

int和Integer有什么区别?

反编译输出: 1: invokesatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 8: invokevirtual #3 // Method java/lang/Integer.intValue:()I 这种缓存机制并不是只有Integer才有,同样存在于其他的一些包装类,比如: Boolean,缓存了true/false对应实例,确切说,只会返回两个常量实例Boolean.TRUE/FALSE。 Short,同样是缓存了-128到127之间的数值。 Byte,数值有限,所以全部都被缓存。 Character,缓存范围'\u0000' 到 '\u007F'。 自动装箱/自动拆箱似乎很酷,在编程实践中,有什么需要注意的吗? 原则上,建议避免无意中的装箱、拆箱行为,尤其是在性能敏感的场合,创建10万个Java对象和10万个整数的开销可不是一个数量级的,不管是内存使用还是处理速度,光是对象头 的空间占用就已经是数量级的差距了。 我们其实可以把这个观点扩展开,使用原始数据类型、数组甚至本地代码实现等,在性能极度敏感的场景往往具有比较大的优势,用其替换掉包装类、动态数组(如ArrayList)等可 以作为性能优化的备选项。一些追求极致性能的产品或者类库,会极力避免创建过多对象。当然,在大多数产品代码里,并没有必要这么做,还是以开发效率优先。以我们经常会使 用到的计数器实现为例,下面是一个常见的线程安全计数器实现。 class Counter { private fnal AtomicLong counter = new AtomicLong(); public void increase() { counter.incrementAndGet(); } } 如果利用原始数据类型,可以将其修改为 class CompactCounter { private volatile long counter; private satic fnal AtomicLongFieldUpdater<CompactCounter> updater = AtomicLongFieldUpdater.newUpdater(CompactCounter.class, "counter"); public void increase() { updater.incrementAndGet(this); } } 2.源码分析 考察是否阅读过、是否理解JDK源代码可能是部分面试官的关注点,这并不完全是一种苛刻要求,阅读并实践高质量代码也是程序员成长的必经之路,下面我来分析下Integer的源 码。 整体看一下Integer的职责,它主要包括各种基础的常量,比如最大值、最小值、位数等;前面提到的各种静态工厂方法valueOf();获取环境变量数值的方法;各种转换方法,比如 转换为不同进制的字符串,如8进制,或者反过来的解析方法等。我们进一步来看一些有意思的地方。 首先,继续深挖缓存,Integer的缓存范围虽然默认是-128到127,但是在特别的应用场景,比如我们明确知道应用会频繁使用更大的数值,这时候应该怎么办呢? 缓存上限值实际是可以根据需要调整的,JVM提供了参数设置: -XX:AutoBoxCacheMax=N 这些实现,都体现在java.lang.Integer源码之中,并实现在IntegerCache的静态初始化块里。 private satic class IntegerCache { satic fnal int low = -128; satic fnal int high; satic fnal Integer cache[]; satic { // high value may be confgured by property int h = 127; String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); ... // range -128, 127 mus be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } ... } 第二,我们在分析字符串的设计实现时,提到过字符串是不可变的,保证了基本的信息安全和并发编程中的线程安全。如果你去看包装类里存储数值的成员变量“value”,你会发现, 不管是Integer还Boolean等,都被声明为“private fnal”,所以,它们同样是不可变类型! 这种设计是可以理解的,或者说是必须的选择。想象一下这个应用场景,比如Integer提供了getInteger()方法,用于方便地读取系统属性,我们可以用属性来设置服务器某个服务 的端口,如果我可以轻易地把获取到的Integer对象改变为其他数值,这会带来产品可靠性方面的严重问题。 第三,Integer等包装类,定义了类似SIZE或者BYTES这样的常量,这反映了什么样的设计考虑呢?如果你使用过其他语言,比如C、C++,类似整数的位数,其实是不确定的,可 能在不同的平台,比如32位或者64位平台,存在非常大的不同。那么,在32位JDK或者64位JDK里,数据位数会有不同吗?或者说,这个问题可以扩展为,我使用32位JDK开发编 译的程序,运行在64位JDK上,需要做什么特别的移植工作吗? 其实,这种移植对于Java来说相对要简单些,因为原始数据类型是不存在差异的,这些明确定义在Java语言规范里面,不管是32位还是64位环境,开发者无需担心数据的位数差 异。 对于应用移植,虽然存在一些底层实现的差异,比如64位HotSpot JVM里的对象要比32位HotSpot JVM大(具体区别取决于不同JVM实现的选择),但是总体来说,并没有行为差 异,应用移植还是可以做到宣称的“一次书写,到处执行”,应用开发者更多需要考虑的是容量、能力等方面的差异。 3.原始类型线程安全 前面提到了线程安全设计,你有没有想过,原始数据类型操作是不是线程安全的呢? 这里可能存在着不同层面的问题: 原始数据类型的变量,显然要使用并发相关手段,才能保证线程安全,这些我会在专栏后面的并发主题详细介绍。如果有线程安全的计算需要,建议考虑使用类 似AtomicInteger、AtomicLong这样的线程安全类。 特别的是,部分比较宽的数据类型,比如foat、double,甚至不能保证更新操作的原子性,可能出现程序读取到只更新了一半数据位的数值! 4.Java原始数据类型和引用类型局限性 前面我谈了非常多的技术细节,最后再从Java平台发展的角度来看看,原始数据类型、对象的局限性和演进。 对于Java应用开发者,设计复杂而灵活的类型系统似乎已经习以为常了。但是坦白说,毕竟这种类型系统的设计是源于很多年前的技术决定,现在已经逐渐暴露出了一些副作用,例 如: 原始数据类型和Java泛型并不能配合使用 这是因为Java的泛型某种程度上可以算作伪泛型,它完全是一种编译期的技巧,Java编译期会自动将类型转换为对应的特定类型,这就决定了使用泛型,必须保证相应类型可以转换 为Object。 无法高效地表达数据,也不便于表达复杂的数据结构,比如vector和tuple 我们知道Java的对象都是引用类型,如果是一个原始数据类型数组,它在内存里是一段连续的内存,而对象数组则不然,数据存储的是引用,对象往往是分散地存储在堆的不同位 置。这种设计虽然带来了极大灵活性,但是也导致了数据操作的低效,尤其是无法充分利用现代CPU缓存机制。 Java为对象内建了各种多态、线程安全等方面的支持,但这不是所有场合的需求,尤其是数据处理重要性日益提高,更加高密度的值类型是非常现实的需求。 针对这些方面的增强,目前正在OpenJDK领域紧锣密鼓地进行开发,有兴趣的话你可以关注相关工程:http://openjdk.java.net/projects/valhalla/ 。 今天,我梳理了原始数据类型及其包装类,从源码级别分析了缓存机制等设计和实现细节,并且针对构建极致性能的场景,分析了一些可以借鉴的实践

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
面试资料:https://cloud.fynote.com/share/d/z0qAVGve
面试资料:https://cloud.fynote.com/share/d/z0qAVGve
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
面试真题:Integer(128)引发的思考
Hey小伙伴们,今天要给大家安利一篇操作实践的文章,相信大家通过仔细阅读,一定会有所收货!
不惑
2024/11/26
4000
面试真题:Integer(128)引发的思考
JAVA面试50讲之4:int和Integer的区别
对于第4条的原因: java在编译Integer i = 100 ;时,会翻译成为Integer i = Integer.valueOf(100);,而java API中对Integer类型的valueOf的定义如下:
用户1205080
2019/01/02
1K0
探究Java的装箱与拆箱:从原始数据类型到引人注目的对象化,有两下子!
咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~
bug菌
2024/08/12
1440
探究Java的装箱与拆箱:从原始数据类型到引人注目的对象化,有两下子!
由自动装箱,引发的关于Integer的有趣现象
看完这篇文章,相信你一定可以很好的理解包装器类以及有些包装器类的自带缓存机制,也可以反手就给面试官说出为什么,下面代码的输出值为true:
东边的大西瓜
2022/05/05
3010
由自动装箱,引发的关于Integer的有趣现象
int和Integer的区别以及使用场景
int 是我们常说的整形数字,是 Java 的 8 个原始数据类型(Primitive Types,boolean、byte 、short、char、int、float、double、long)之一。Java 语言虽然号称一切都是对象,但原始数据类型是例外。
刺槐儿
2023/11/25
1.6K0
深度解析Java中的Integer类原理及方法实现
在Java编程中,我们经常使用Integer类来处理整数值。接下来,让我们通过结合Integer类的源码、设计思想以及方法和接口的设计,详细探讨其底层原理。
GeekLiHua
2025/01/21
1170
面试官:兄弟,说说基本类型和包装类型的区别吧
POJO 的英文全称是 Plain Ordinary Java Object,翻译一下就是,简单无规则的 Java 对象,只有属性字段以及 setter 和 getter 方法,示例如下。
Remember_Ray
2020/01/21
3.6K1
Java基础--int与Integer区别
java在最初设计的时候就提供了8种基本数据类型和对应的8种引用类型。 基本数据类型|封装类型 ---|--- byte|Byte short|Short int|Integer long|Long float|Float double|Double boolean|Boolean char |Character
河岸飞流
2020/02/13
5020
Java基础系列1:深入理解Java数据类型
当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型。
王金龙
2020/02/17
5640
夯实Java基础系列8:深入理解Java内部类及其实现原理
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/09/28
3.6K0
Java 中为什么设计了包装类
在 Java 中,万物皆对象,所有的操作都要求用对象的形式进行描述。但是 Java 中除了对象(引用类型)还有八大基本类型,它们不是对象。那么,为了把基本类型转换成对象,最简单的做法就是「将基本类型作为一个类的属性保存起来」,也就是把基本数据类型包装一下,这也就是包装类的由来。
飞天小牛肉
2021/03/18
1.3K0
Java 中为什么设计了包装类
必考:从字节码层面看自动拆装箱的原理
上一篇文章中,我们分享包装类的缓存机制时,提到了自动装箱的问题。今天我们就重点分享自动装箱的原理,及其相关的知识点(笔试必考)!
程序视点
2023/11/16
1690
必考:从字节码层面看自动拆装箱的原理
面试官:兄弟,说说基本类型和包装类型的区别吧
六年前,我从苏州回到洛阳,抱着一幅“海归”的心态,投了不少简历,也“约谈”了不少面试官,但仅有两三个令我感到满意。其中有一位叫老马,至今还活在我的手机通讯录里。他当时扔了一个面试题把我砸懵了:说说基本类型和包装类型的区别吧。
沉默王二
2019/09/29
5800
面试官:兄弟,说说基本类型和包装类型的区别吧
int 和 integer :装箱和拆箱的过程,会用到什么方法,你觉得这个会对性能有影响吗,原因是什么(百度一面)
今天继续来讲面试,已经出了很多java一面真题系列文章了,之后也会整理成一个系列,欢迎持续关注哦。
用户7656790
2020/09/01
2.7K0
聊聊面试-int和Integer的区别
最近面试了很多候选人,发现很多人都不太重视基础,甚至连工作十几年,项目经验十几页的老程序员,框架学了一大堆,但是很多 Java 相关的基础知识却很多都答不上来。还有很多人会回答,只知道要用,但是从来不会去看看它具体是怎么实现的。
phoenix.xiao
2020/08/05
4750
Java基础笔记之数据类型
(二)包装类型(与基本数据类型一一对应,把基本数据类型封装成对象的形式)
CherishTheYouth
2019/07/30
3760
Java基础笔记之数据类型
JAVA自动拆装箱、equals与==比较
自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。
chenchenchen
2023/01/30
4370
Java的基本数据类型
1. Java 的基本数据类型都有哪些各占几个字节 2. short s1 = 1;s1 =s1 + 1;有错吗?short s1 = 1;s1 += 1有错吗; 前者不正确,后者正确。对于s
海拥
2021/08/23
3330
Integer与int之间的秘密
相信各位Java行业的”打工人“,不论在日常工作还是学习中,都会接触整数类型的数值,并且还能深情的说出”整数类型一般分为4种“。
用户8639654
2021/07/15
4990
Java基本数据类型、包装类及拆装箱详解
Java的基本数据类型和对应的包装类是Java语言中处理数据的两个关键概念。基本数据类型提供了简单而高效的方式来存储数据,而包装类使得基本数据类型具有对象的特性。本文将深入探讨基本数据类型与包装类的应用场景及详细描述,并对自动拆箱和装箱的源码实现进行分析。
修己xj
2023/12/05
6520
Java基本数据类型、包装类及拆装箱详解
相关推荐
面试真题:Integer(128)引发的思考
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档