前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >由自动装箱,引发的关于Integer的有趣现象

由自动装箱,引发的关于Integer的有趣现象

作者头像
东边的大西瓜
发布2022-05-05 12:26:53
2690
发布2022-05-05 12:26:53
举报
文章被收录于专栏:吃着西瓜学Java

前言

看完这篇文章,相信你一定可以很好的理解包装器类以及有些包装器类的自带缓存机制,也可以反手就给面试官说出为什么,下面代码的输出值为true:

代码语言:javascript
复制
       Integer a = 127;
       Integer b = 127;
       System.out.println(a==b);
       //打印结果为true

什么是包装器类?

Java是一门面向对象语言,万物皆可对象,当然基本数据类型也不能例外,所有的基本数据类型都有一个与之对应的类,这些类被称为基本数据类型的包装器类。

基本数据类型

包装器类

short

Short

int

Integer

long

Long

byte

Byte

float

Float

double

Double

char

Character

boolean

Boolean

这些包装器类都如同String类一样都是不可变的,查看源码也都能发现都是被final关键字修饰的,当然也是不能继承的。

什么是自动装箱和自动拆箱?

  • 自动装箱可以理解为基本数据类型转化成对应的包装器类;
  • 自动拆箱可以理解为包装器类转化为对应的基本数据类型;

对应标题,这里我们拿Integer举例,查看下面两行代码:

代码语言:javascript
复制
       Integer a = 1; //自动装箱
       int b = new Integer(2); //自动拆箱

通过查看其字节码,我们可以发现,自动装箱会调用Valueof()方法,自动拆箱会调用intValue()方法。

自动拆箱之自带缓存

缓存可以节省内存、提高速度,Java的许多包装器类都提供了缓存机制,以便在自动装箱过程中,可以直接取出预先缓存的对象,提高效率。

  • 提供缓存机制的包装器类:Short、Integer、Long、Character、Byte ,而且范围为[-128,127]。
  • 不提供缓存机制的包装器类:Boolean、Float、Double,前者是因为只有TRUE/FALSE两种可能,不过也可以用算作变相缓存;后者是因为存在小数点,一定范围内数值过多,如果缓存则弊大于利。

以Integer为例,分析其Valueof源码:

我们再来看一下IntegerCache这个内部类,注意红箭头指向的那段注释,大意为最高值high是可配置的:

总结: 当我们使用自动拆箱来获取Integer类时,如果在[-128,high]范围内,则将返回缓存对象,这里的high默认为127,但是是可配置的。

知识补充之“==”比较的是什么?

  • 数据类型为基本数据类型时“==”比较的是其值(value)
  • 对象数据类型时“==”比较的则是对象的地址

因此包装类比较时比较的同样是地址,如果在缓存范围内,则为同一对象(相等),否则为不同对象(不相等)。

代码实战:

代码一:

代码语言:javascript
复制
    public static void main(String[] args) {
       Integer a = 127;
       Integer b = 127;
       Integer c = 128;
       Integer d = 128;
       System.out.println(a==b);
       System.out.println(c==d);
    }


输出结果:

代码二:

代码语言:javascript
复制
    public static void main(String[] args) {
       Integer a = 127;
       Integer b = 127;
       Integer c = new Integer(127);
       Integer d = new Integer(127);
       System.out.println(a==b);
       System.out.println(c==d);
    }

输出结果:

总结:

因为a,b是使用自动装箱来完成创建的,并且在默认缓存范围[-128,127],则a和b都是指向缓存的同一个对象,所以“==”比较结果为:true

在代码一中,c和d的值为128,也都是使用自动装箱来完成创建的,但是超过了默认缓存范围[-128,127],则调用new方法创建不同的对象,“==”比较结果为:false 在代码二中,c和d的值为127,虽然在默认缓存范围[-128,127]中,但是是通过new方法创建的不同对象,所以为不同对象,“==”比较结果为:false

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 吃着西瓜学Java 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 什么是包装器类?
  • 什么是自动装箱和自动拆箱?
  • 自动拆箱之自带缓存
  • 知识补充之“==”比较的是什么?
  • 代码实战:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档