装箱和拆箱
java呢是一门面向对象的语言,正所谓对象,是指引用数据类型的,但是后面会用到基本数据类型的次数越来越多,所以要想办法讲基本数据类型转换为引用数据类型。
8种基本数据类型和void都分别设计了包装类:
byte<-->Byte
short<-->Short
int<-->Integer
long<-->Long
float<-->Float
double<-->Double
char<-->Character
boolean<-->Boolean
void<-->Void
装箱:把基本数据类型的数据转换为包装类的对象,这个过程称为装箱。
拆箱:把包装类的对象拆解为基本数据类型的数据,这个过程称为拆箱。
基本数据类型-->装箱-->包装类的对象
包装类的对象-->拆箱-->基本数据类型
拆箱操作:从包装类中取出被包装的数据,利用从Number类中继承而来的一系列xxxValue方法完成
不同类型的拆箱操作就使用不同的xxxValue()方法来操作。
/*
在JDK1.5之前:
装箱和拆箱必须手动进行,必须调用特定的方法或构造器来完成这个过程。
*/
int num = 1;
Integer objNum = new Integer(num); //装箱过程
int a = objNum.intValue(); //拆箱过程
byte x = a;
Byte objX = new Byte(x);
byte x1 = objX.byteValue();
//拆箱就是调用xxxValue方法获得内部数据。除了int外,double也是一样的操作。而boolean虽然是Object的子类,但也有同样的操作。
但是在我们的JDK1.5之后是可以自动拆箱装箱的。
//JDK1.5之后:
int value = 1;
Integer objValue = value;//自动装箱
//如果编译器是JDK5之前,这句编译不通过
int b = objValue;//自动拆箱
//自动装箱和自动拆箱仅限于对应类型之间。
// Double d = num;//错误,因为num是int类型,它对应的包装类是Integer,不是Double
//装箱过程不能直接自动跨两步:第一步,先自动升级为double,第二步,再自动装箱为Double
Double d = (double)num;
// int c = d;//错误,因为d是Double类型,它对应的基本数据类型是double,不是int
//拆箱过程,最多只能拆箱为double类型,而double类型也不能直接赋值给int,因为double>int
// int c = (int)d;//错误,因为d是Double类型,引用数据类型无法通过强制类型转换,换行为基本数据类型的int
int c = d.intValue();//手动拆箱。
System.out.println("---------------------------");
//为什么要装箱或拆箱?
//后面有集合等这样的API,例如:ArrayList
//集合:就是容器,有点像数组一样的容器,就是装对象的容器
//集合有一个特点,只能装对象
// ArrayList<int> list = new ArrayList<int>();//错误,因为集合只支持对象,泛型也只支持引用数据类型
ArrayList<Integer> list = new ArrayList<Integer>();
//想要把1,2,3,4,5这些数据装到容器中时,必须用到包装类,必须装箱
list.add(1);//自动装箱 int->Integer对象
list.add(2);//自动装箱 int->Integer对象
list.add(3);//自动装箱 int->Integer对象
list.add(4);//自动装箱 int->Integer对象
list.add(5);//自动装箱 int->Integer对象
//要把集合容器中的5个对象,求和'
int sum = 0;
for(int i=0; i<list.size(); i++){
Integer element = list.get(i);
sum += element;//自动拆箱
}
System.out.println("sum = " + sum);
}
}
虽然是自动装箱,但是自动装箱和手动装箱还是不一样的。
public class Test{
public static void main(String args[]) {
Integer x1= 10; // 自动装箱是在常量池中的。
Integer x2= 10;
Integer x3= new Integer(10); //手动装箱的话是新new的在堆中新开辟的内存空间。
System.out.println(x1 == x2);
System.out.println(x1== x3);
System.out.println(x2== x3);
System.out.println(x2.equals(x3)); //比较内容完全一致的话还是用equals来比较
}
}
自动装箱会保存对象到对象池中,而构造装箱则是会重新开辟新的堆内存空间。因此为了保证对象的有效比较,最好使用equals方法进行比较。