java自动封箱_5分钟彻底理解-Java自动装箱、拆箱

什么是自动装箱,拆箱

先抛出定义,Java中基础数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱,装箱和拆箱可以让我们的代码更简洁易懂

Java中基础数据类型与它们对应的包装类见下表(共8种):

原始类型

包装类型

boolean

Boolean

byte

Byte

char

Character

float

Float

int

Integer

long

Long

short

Short

double

Double

当表格中左边列出的基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱.

进行 = 赋值操作(装箱或拆箱)

进行+,-,*,/混合运算 (拆箱)

进行>,

调用equals进行比较(装箱)

ArrayList,HashMap等集合类 添加基础类型数据时(装箱)

我们看一段平常很常见的代码

public void testAutoBox() {

List list = new ArrayList<>();

list.add(1.0f);

float firstElement = list.get(0);

}

复制代码

list集合存储的是Float包装类型,我传入的是float基础类型,所以需要进行装箱,而最后的get方法返回的是Float包装类型,我们赋值给float基础类型,所以需要进行拆箱,很简单,安排的明明白白

具体自动装箱,拆箱,代码是如何实现的

既然编译器帮我们自动进行了装箱,拆箱,那么编译器到底做了些什么,要搞清楚这些,最简单直接的方式就是看类经过编译器编译后的字节码,下面是上面一段代码的字节码实现

public testAutoBox()V

L0

LINENUMBER 15 L0

NEW java/util/ArrayList

DUP

INVOKESPECIAL java/util/ArrayList. ()V

ASTORE 1

L1

LINENUMBER 16 L1

ALOAD 1

FCONST_1

INVOKESTATIC java/lang/Float.valueOf (F)Ljava/lang/Float;

INVOKEINTERFACE java/util/List.add (Ljava/lang/Object;)Z

POP

L2

LINENUMBER 17 L2

ALOAD 1

ICONST_0

INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object;

CHECKCAST java/lang/Float

INVOKEVIRTUAL java/lang/Float.floatValue ()F

FSTORE 2

L3

LINENUMBER 18 L3

RETURN

复制代码L0,对应我们代码的第一行,new了一个ArrayList,并赋值给了1号引用(就是list)。

L1,先加载list到栈顶,然后FCONST_1指令就是从常量池加载1.0f浮点数并压入栈顶(这一块知识,见附录1),然后调用了Float类的静态 valueOf方法,进行装箱

,然后调用list的add方法。

L2,先加载list到栈顶,从常量池获取0(float,int,long,double等基础类型初始值都是0),调用list的get方法,检查是否能转换,调用了Float的floatValue方法,进行拆箱

,存储得到的浮点数。

###所以结果很明显了,以float和Float为例,装箱就是调用Float的valueOf方法new一个Float并赋值,拆箱就是调用Float对象的floatValue方法并赋值返回给float。其他基础类型都是大同小异的,具体可以查看源码。

##自动装箱、拆箱中的坑

###面试题中经常会有考点就是考察面试者对Java中自动装箱、拆箱是否了解透彻,比如下面这一道面试题?

public void testAutoBox2() {

//1

int a = 100;

Integer b = 100;

System.out.println(a == b);

//2

Integer c = 100;

Integer d = 100;

System.out.println(c == d);

//3

c = 200;

d = 200;

System.out.println(c == d);

}

复制代码

请问执行结果是多少?

题目很常见啦,客官别见笑,我们来分析一下,

第1段代码,基础类型a与包装类b进行==比较,这时b会拆箱,直接比较值,所以会打印 true

第2段代码,二个包装类型,都被赋值了100,所以根据我们之前的解析,这时会进行装箱,调用Integer的valueOf方法,生成2个Integer对象,引用类型==比较,直接比较对象指针,这里我们先给出结论,最后会分析原因,打印 true

跟上面第2段代码类似,只不过赋值变成了200,直接说结论,打印 false

a964deb7b17ae3f769e614d94ea77e00.png

结果是不是很诡异,我们直接去看Integer类valueOf方法的实现(JDK8的实现)

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

复制代码

可以看到,这里的实现并不是简单的new Integer,而是用IntegerCache做一个cache,cache的range是可以配置的

private static class IntegerCache {

static final int low = -128;

static final int high;

static final Integer cache[];

static {

int h = 127;

String integerCacheHighPropValue =

sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

if (integerCacheHighPropValue != null) {

try {

int i = parseInt(integerCacheHighPropValue);

i = Math.max(i, 127);

// Maximum array size is Integer.MAX_VALUE

h = Math.min(i, Integer.MAX_VALUE - (-low) -1);

} catch( NumberFormatException nfe) {

// If the property cannot be parsed into an int, ignore it.

}

}

high = h;

cache = new Integer[(high - low) + 1];

int j = low;

for(int k = 0; k < cache.length; k++)

cache[k] = new Integer(j++);

....

复制代码

这是IntegerCache静态代码块中的一段,默认Integer cache 的下限是-128,上限默认127,可以配置,所以到这里就清楚了,我们上面当赋值100给Integer时,刚好在这个range内,所以从cache中取对应的Integer并返回,所以二次返回的是同一个对象,所以==比较是相等的,当赋值200给Integer时,不在cache 的范围内,所以会new Integer并返回,当然==比较的结果是不相等的。

###以上

附录1:JVM字节码整型的入栈指令有4个,分别是:

iconst(0~5分别对应iconst_0、iconst_1、iconst_2、iconst_3、iconst_4、iconst_5,-1对应iconst_m1)

bipush (-128~127)

sipush (-32768~32767)

ldc(-2147483648~2147483647)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值