java包装类的小结

转载自 http://macemers.iteye.com/blog/860631

Java包装类,Wrapper~由于在java中,数据类型总共可分为两大种,基本数据类型(值类型)和类类型(引用数据类型)。基本类型的数据不是对象,所以对于要将数据类型作为对象来使用的情况,java提供了相对应的包装类。对于8种数据类型的包装类分别是:

int—Integer
char—Character
float—Float
double—Double
byte—Byte
short—Short
long—Long
boolean–Boolean

java中除了Float,Double之外,都提供了常量池,但只有数值在-128~127之间才会使用常量池。

所谓装箱,就是把基本类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double,等等。

所谓拆箱,就是跟装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为值类型的数据

J2SE5.0后提供了自动装箱与拆箱的功能,此功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的方法,决定是否进行装箱或拆箱动作。

自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。

自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取出来,没必要再去调用intValue()和doubleValue()方法。

自动装箱,只需将该值赋给一个类型包装器引用,java会自动创建一个对象。例如:

Integer i=100;//没有通过使用new来显示建立,java自动完成。

自动拆箱,只需将该对象值赋给一个基本类型即可。例如:int j=i;

int i = 10;
Integer j =new Integer(i); //手动装箱操作  
int k = j.intValue();      //手动拆箱操作  

int i = 11;
Integer j = i; //自动装箱
int k = j //自动拆箱

然而在Integer的自动装拆箱会有些细节值得注意:

public static void main(String[] args) {
    Integer a=100;
        Integer b=100;

        Integer c=200;
        Integer d=200;

        System.out.println(a==b);   //1
        System.out.println(a==100); //2

        System.out.println(c==d);   //3
        System.out.println(c==200); //4
   }

在java种,”==”是比较object的reference而不是value,自动装箱后,abcd都是Integer这个Oject,因此“==”比较的是其引用。按照常规思维,1和3都应该输出false。但结果是:
true
true
false
true

结果2和4,是因为ac进行了自动拆箱,因此其比较是基本数据类型的比较,就跟int比较时一样的,“==”在这里比较的是它们的值,而不是引用。

对于结果1,虽然比较的时候,还是比较对象的reference,但是自动装箱时,java在编译的时候 Integer a = 100; 被翻译成-> Integer a = Integer.valueOf(100);
关键就在于这个valueOf()的方法。

public static Integer valueOf(int i) {   
final int offset = 128;   
if (i >= -128 && i <= 127) { // must cache   
return IntegerCache.cache[i + offset];   
}   
return new Integer(i);   
}   
private static class IntegerCache {   
private IntegerCache(){}   
static final Integer cache[] = new Integer[-(-128) + 127 + 1];   
static {   
for(int i = 0; i < cache.length; i++)   
cache = new Integer(i - 128);   
}   
} 

根据上面的jdk源码,java为了提高效率,IntegerCache类中有一个数组缓存了值从-128到127的Integer对象。当我们调用Integer.valueOf(int i)的时候,如果i的值是>=-128且<=127时,会直接从这个缓存中返回一个对象,否则就new一个Integer对象。

public class TestWhile{ //1
  public static void main(String[] args)//2
  {
  Integer i=0;//3
  Integer j=0;//4
  // Integer i=new Integer(0);//5
  // Integer j=new Integer(0);//6
  while(i<=j & i>=j & i!=j)//7
  { //8
  System.out.println("0000");//9
  }

  }

}

那一行是拆箱?while循环里的条件看似不成立,可为什么可以运行(去掉第5、6行的注释后)?
解答:
这种情况下,循环不能运行。
对于Integer类型,<,<=,>,>=操作将导致拆箱操作,也就是调用Integer的intValue()方法得到相应的基本类型值,然后比较。
但是,==,!=比较的,是对象的引用(Reference)。

Integer i = 0;//3
Integer j = 0;//4
这两句使用装箱操作,也就是调用Integer.valueOf(int i);注意,不是使用new。
由于0在 -128–127之间,根据上述,i和j引用的是同一个对象。
综上,i<=j & i>=j & i!=j中,
i<=j 和 i>=j都成立,而i!=j不成立,因为i和j引用的是同一个对象。

故此,循环不会执行。

注释掉3,4两句,使用5,6两句时,i和j引用的不是同一个对象,所以i!=j成立。i<=j & i>=j & i!=j成立,循环条件总是成立的,while (i <= j & i >= j & i != j)成为无穷循环,不断输出。

总结,对于要比较Object的值,最稳妥的方法还是调用equals()这个方法(比较的是数值,或者用compareTo(包装类),返回0时,说明相等),而不是使用==,因此会比较其引用。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值