八个基本的包装类
在这八个类名中,除了Integer和Character类以外,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写而已。
包装类用途:
- 作为和基本数据类型对应的类型存在,方便设计对象的操作,如Objec[]、集合等操作。
- 包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法(这些操作方法的作用是在基本数据类型、包装类对象、字符串之间提供相互之间的转化!)。
Integer例子,其他包装类对象同理:
//基本数据类型转成包装类对象。
Integer a = new Integer(3);
Integer b = Integer.valueOf(3);
//把包装类对象转成基本数据类型
int c = b.intValue();
double d = b.doubleValue();
//把字符串转成包装类对象
Integer e = new Integer("998849");
Integer f = Integer.parseInt("49755");
//把包装类对象转成字符串
String str = f.toString();
//常见的常量
System.out.println("int类型的最大整数:" + Integer.MAX_VALUE);
自动装箱:
基本类型的数据处于需要对象的环境中时,会自动转为“对象”。如果反编译.class文件发现实际上调用的是valueOf这个方法。valueOf涉及包装类缓存问题,具体如下。
包装类缓存问题
整型、char类型所对应的包装类,在自动装箱时,对于-128 ~ 127之间的值会进行缓存处理,其目的是提高效率。缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。
System.out.println("----------------------");
Integer integer_1=Integer.valueOf(100);
Integer integer_2=Integer.valueOf(100);
System.out.println(integer_1==integer_2);
Integer integer_3=Integer.valueOf(200);
Integer integer_4=Integer.valueOf(200);
System.out.println(integer_3==integer_4);
System.out.println(integer_3.equals(integer_4));
输出的true, false, true
因为类在加载时已经创建了对象,反编译该类的字节码文件发现第二行代码和第三行代码实际调用的都是valueOf该方法代码如下:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerChache 部分代码如下:
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;
}
所以只要在-128~127之间,就直接指向已经创建好了的cache数组中。integer_1,integer_2 自然也就相等了。
自动拆箱;
每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法。
例1:
Integer i = 5;
int j = i;
例2:程序会报空指针异常的错误(对象为空,但是你却调用了它的方法),说明调用了C函数。
Integer c = null;
int d = c;//自动拆箱,调用了c.intValue()
自动装箱过程是通过调用包装类的valueOf()方法实现的,而自动拆箱过程是通过调用包装类的xxxValue()方法实现的(xxx代表对应的基本数据类型,如intValue()、doubleValue()等)。自动装箱与拆箱的功能事实上是编译器来帮的忙,编译器在编译时依据您所编写的语法,决定是否进行装箱或拆箱动作