java隐士转换和装箱_深入理解Java装箱与拆箱

写给小白看的Java基础知识,阅读本文大概需要7分钟

Java中有8种基础数据类型,boolean,char,byte,short,int,long,float,double。从jdk5开始提供了自动装箱拆箱机制,对应的包装类型即Boolean,Character,Byte,Short,Integer,Long,Float,Double。

首先解释一下为什么要引入装箱和拆箱机制,因为Java是面向对象的语言啊,这样使用了包装类后,就可以调用object的一些方法了。都是个人见解,欢迎指正。

Integer i=10;//装箱int n=i;//拆箱

装箱就是将基础数据类型转换为对应的包装器类型;

拆箱就是将包装器类型转换为对应的基础数据类型;

那装箱和拆箱是如何实现的呢,其实我们在Integer源码中可以查看,装箱使用了valueOf()方法,拆箱使用了intValue()。

public static Integer valueOf(int i) {

//low=-128

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

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

return new Integer(i);

}

public int intValue() {

return value;

}

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() {}

}

从上述方法的具体实现可以知道,vauleOf已经在cache中创建了[-128,127]范围的对象数组,当新建的Integer数值在该范围中,会从对象数组里返回相应的对象。如果超出范围会重新创建一个对象。

经过上面的解释我们可以很好地理解上图的结果,i1和i2都在[-128,127]中,所以返回的是同一个对象,结果为true。而i3和i4超出该范围,所以两次都要新建对象,于是结果返回false。

而对于其他几种包装类型,也都是利用对应的vauleOf和(Boolean/Character/Byte/Short/Long/Float/Double)Value方法实现装箱,拆箱。其中Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的,Double、Float的valueOf方法的实现是类似的,大家可以在源码中查看。

Integer a = 1;

Integer b = 2;

Integer c = 3;

Integer d = 3;

Integer e = 200;

Integer f = 200;

Long g = 3L;

Long h = 2L;

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

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

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

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

System.out.println(g==(a+b));//true 当==两边有算式时,就比较数值(自动拆箱)

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

System.out.println(g.equals(a+h));//true

在解释结果前先来说说==和euqals的区别:

== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象(基本数据类型比较的是值,引用数据类型比较的是内存地址)。

equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:

情况 1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。

情况 2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。

这里解释一下后三个的结果,==两边如果有算式的话,那就只比较内容而不是地址,结果为true。倒数第二个中,a+b和g的类型不同,自然地址也不相同,结果为false。最后一个a+h结果会发生隐式转换,所以结果为true。

----------------------------------------------------------------------------------------------

欢迎关注我的公众号预备码农

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值