包装类

包装类的概述:

java中有8个基本类型:byte,short,int,long,float,double,char,boolean。它们是以值的形式存在于内存中,而不是对象。它们不是Object的子类,不能参与面向对象的开发。
若想将基本类型以对象的形式存在,就需要将它定义成一个类,然而java给八大基本数据类型提供相应的包装类:

byte    java.lang.Byte
short   java.lang.Short
int     java.lang.Integer
long    java.lang.Long
float   java.lang.Float
double  java.lang.Double
char    java.lang.Character
boolean java.lang.Boolean
其中除了Character与Boolean的父类是Object之外,其余的都是继承自:java.lang.Number

自动装箱和自动拆箱操作(JDK1.5后的特性)

当我们需要将基本类型转换为包装类时,我们可以调用包装类的一个静态方法valueOf():
Integer i = Integer.valueOf(1);
Double d = Double.valueOf(1.1);
.......
当我们需要将包装类转换为基本类型时,我们可以使用包装类的方法xxxValue()方法(这里不同的包装类方法名不完全一致,但都是以Value结尾):
Integer i = new Integer(1);
int n = i.intValue();
....

虽然我们可以通过上述的方法在基本类型与包装类之间相互转换。但是在实际编写代码时相对还是比较麻烦的。java在1.5版本后推出了一个新的特性:自动拆装箱。

//可以自动将包装类转换为基本类型 自动拆箱
int i = new Integer(1);
//可以自动将基本类型转换成包装类 自动装箱
Integer in = 1;

java自动拆装箱的原理

    事实上JVM不支持该特性,自动拆装箱只是编译器在编译过程中的"预处理"操作。编译器在看到需要在包装类与基本类型之间转换时,会在编译为字节码时进行改变:
源代码中 编译后的字节码中
Integer a = 100 => Integer a = Integer.valueOf(100);
Integer b = 200 => Integer b = Integer.valueOf(200);
Integer c = a+b => Integer c = Integer.valueOf (a.intValue( ) + b.intValue( ));
double d = c => double d = c . doubleValue( );

创建对象时涉及到常量池的问题

Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
Integer i7 = 200;
Integer i8 = 200;
System.out.println("i1=i2\t" + (i1 == i2)); //true
System.out.println("i1=i2+i3\t" + (i1 == i2 + i3)); //true
System.out.println("i4=i5\t" + (i4 == i5)); //false
System.out.println("i4=i5+i6\t" + (i4 == i5 + i6)); //true  
System.out.println("i7=i8\t" + (i7 == i8)); //false

Integer内部的源码:

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


static {
        for(int i = 0; i < cache.length; i++)
        cache[i] = new Integer(i - 128);
    }

Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),它维护了一个Integer数组cache,长度为(128+127+1)=256;Integer类中还有一个Static Block(静态块)
  从这个静态块可以看出,Integer已经默认创建了数值【-128-127】的Integer缓存数据。所以使用Integer i1=40时,JVM会直接在该在对象池找到该值的引用。
  也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查找有木有值为40的对象,如果有直接返回该对象的引用;如果没有,则使用New keyword创建一个对象,并返回该对象的引用地址。因为Java中【==】比较的是两个对象是否是同一个引用(即比较内存地址),i2和i2都是引用的同一个对象,So i1==i2结果为”true“;而使用new方式创建的i4=new Integer(40)、i5=new Integer(40),虽然他们的值相等,但是每次都会重新Create新的Integer对象,不会被放入到对象池中,所以他们不是同一个引用,输出false。

  对于i1==i2+i3、i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5、i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True。
  
当数值大于127时,就不会在使用Integer中的缓存池,而是会new 一个对象返回 所以 i7 == i8 结果为:”false“

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值