java整形包装类自动拆箱范围_有关Java包装类的自动装箱和拆箱--使用注意事项...

事出有因

在最近准备安卓面试的过程中,一位资深的大神问了我关于装箱和拆箱的一些知识点。无奈小弟平时没怎么关注这个方面的知识点,拿来就是用,完全没有没有考虑到使用上的性能损耗和一些注意事项问题。所以经历此面试之后,决定好好复习一下关于这方面的知识点,并总结出这篇文章,供自己日后快速复习,同时也希望本篇文章能给各位看官带来收益。

例子1

· 知识点

1 自动装箱 & 自动拆箱

2 比较符“==”和“equal”,在使用上的注意事项

public static void main(String[] args) {

Integer a = 1;

Integer b = 2;

Integer c = 3;

Integer d = 3;

Integer e = 220;

Integer f = 220;

Long g = 3L;

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

System.out.println(e == f);

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

System.out.println(c.equals(a + b));

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

System.out.println(g.equals(a + b));

}

复制代码

小伙伴们先猜想上面程序输出的结果,认真的思考一下。

· 解释

在程序中变量:a,b,c,d,e,f,g都是对基本数据包装类,在初始化这些变量的时候,实际上java编译器帮我们使用装箱来赋值。例如:Integer a = 1; 编译后换算成 Integer a = Integer.valueOf(1); 这个过程就被称为装箱啦,需要注意一点的是变量a为Integer对象类型,为实际保存值的地址引用。

当打印:c == d的时候,此时两者的对象类型都是Integer,那么此时比较的是两者的地址引用。此处的结果返回为true,那么我们能间接得出结论:c和d都指向同一个对象,指向的对象值为3

当打印:e == f的时候,同样的此时两者的对象类型都是Integer,那么此时比较的是两者的地址引用。但是此处返回的结果为false,那么我们能间接得出结论:e和f指向不同的对象,但是对象的值都为220。

对比上面两条结果,我们是否有疑问。为啥第一条打印为true,第二条打印为false。想要搞懂这其中的原因,那么就需要知道Integer中的Cache的概念,下面贴出其中的源码:

private static class IntegerCache {

static final int low = -128;

static final int high;

static final Integer cache[];

static {

// high value may be configured by property

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++);

// range [-128, 127] must be interned (JLS7 5.1.7)

assert IntegerCache.high >= 127;

}

private IntegerCache() {}

}

复制代码

上面的源码不是特别复杂,各位看官可以先大致观摩一下,再来看我的解析,理解起来能够事半功倍。

源码解析:IntegerCache是Integer的静态内部类,用来缓存Integer对象。使用数组的形式来缓存,并且数组的大小为256,缓存值的范围为:[-128 ,127]。如果值的取值范围没有在这个区间中,那么这个对象将不会保存

结论:值为3的Integer对象,会保存在缓存中。值为220,不在保存的区间范围内,所以每次都是创建新的Integer类型对象

当打印“c == (a+b)” 的时候,结果为true。为什么为true?

我来解析一下这个过程:

a+b等同于a.value+b.value , 其中a.value = 1,b.value = 2 ,所以:a+b的结果为基本类型3(这个过程就是拆箱的过程,一般在遇到算数运算符的时候,包装类型就是自动拆箱)“c == (a+B)” 就等同于 “c == 3”,因为此时的c的类型为Integer,所以需要拆箱比较,最终的比较形式为:c.value == 3

当打印“c.equals(a+b)”的时候,结果也为true

和上面一样,解析一下过程:a+b的解析和上面一样。我们重点来看"c.equals(a+b)",Integer.equals()方法需要传入Object对象,那么a+b需要装箱变为Integer对象。程序就变成“c.equals(Integer.value(3))”,所以结果为true

注意事项:包装类的装箱和拆箱涉及到性能损耗,因为程序需要多执行几步。涉及到基本算术运算符,就会涉及到拆箱,变量初始化涉及到装箱

当打印“g == (a + b)”,因为(a+b)得到结果为基本类型3。变量g的类型为Long,当执行g == 3的时候需要拆箱变成3 == 3 。所以得到的结果为true。

当打印“g.equals(a + b),结果为false。为什么结果不是true,因为:g的类型为Long,那么Long.equals()方法比较的对象类型也需要为Long,源码如下:

public boolean equals(Object obj) {

if (obj instanceof Long) {

return value == ((Long)obj).longValue();

}

return false;

}

复制代码

因为a+b得到的结果为整型3,所以程序变成g.equals(Integer.valueOf(3)),可以看到两者对象的类型都不相同,尽管他们的值都为3,但程序结果还是返回false

注意事项:当使用不同包装类的equals方法时候,需要注意比较的类型不同结果直接返回false

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[有关Java包装类的自动装箱和拆箱--使用注意事项]http://www.zyiz.net/tech/detail-128900.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值