什么是包装类?
java中的基本数据类型如int,double等不是对象,无法通过向上转型获取到Object提供的方法.
而String却可以,因为String是一个对象而不是一个类型。
基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类,为8中简单类型提供对象形式,让Object统一所有数据。
包装类顾名思义就是将基本的数据类型以及一些辅助方法包装到类中,例如自己实现一个int的包装类:
public class test { public static void main(String[] args) { Inter in = new Inter(5); } } //自定义一个类,将int型包装成对象 class Inter { private int num; public Inter(int num) { this.num = num; } }
java 提供的包装类:
虽然上面的Inter类能实现一些辅助功能,而且可以支持泛型反射等功能,但是如果如果每次使用都自己封装这么一个类的话,就太繁琐了。所以,java为我们提供了基本数据类型的包装类,
基本数据类型 包装类类型 *int Integer *char Character *除这两种外其他6种基本类型的包装类都是首字母大写 *double Double *short Short *float Float *byte Byte *long Long *boolean Boolean
包装类与基本数据类型的转换:
因为基本数据类型 默认值是0,所以如果要是区分 0 和null 就比较麻烦了。比如统计学生成绩,使用基本数据类型很难区分考试考0 分的和缺考没有参加考试的。而使用包装类就可以很好的解决这个问题了,引用类型不赋值就为null。
下面解释一下基本数据类型与String之间的转换:
int 转换为 Integer
int 转换为 Integer有两种方式,可以通过包装类的构造方法进行转换或者通过Integer提供的静态方法valueOf进行转换
int i = 12; Integer ii = new Integer(i);//通过构造方法转换 System.out.println(ii); //通过Integer提供的静态方法进行转换 Integer ii02 = Integer.valueOf(i); System.out.println(ii +"\t" + ii02);
将Integer 转换为 int
Integer integer01 = new Integer(10); int i2 = integer01.intValue();
int 转为String
这个很简单,可以通过字符串拼接实现:
int i02 = 20; //通过字符串拼接实现转换 String s = i02 + "";
String 转换为 int
常用,Integer提供的parseInt方法进行转换,返回类型为int
但是只有字符串里面存的是数字类型的时候才可以转换,
否则会报 java.lang.NumberFormatException(数据格式转换异常)
String ss = "456"; int i3 = Integer.parseInt(ss);
String 转换为Integer
//同理字符串不能存数字 String ss2 = "789"; //通过Integer提供的valueOf方法转换,返回值类型是Integer。 Integer ii2 = Integer.valueOf(ss2); //或者通过构造方法进行转换 Integer in = new Integer(ss2);
Integer转换为 String
//利用Integer的toString方法进行转换 Integer in2 = new Integer("123"); String s2 = in2.toString(); //或者利用字符串拼接转换 String s3 = in2 + "";
拆箱与装箱
装箱:
将基本数据类型封装为包装类对象,利用每一个包装类提供的构造方法实现装箱操作。
拆箱:
将包装类中包装的基本数据类型数据取出。
// 装箱 Integer integer = new Integer(10); // 拆箱 int int111 = integer.intValue();
JDK1.5之后提供自动拆装箱。
// 自动装箱时,默认调用的是valueOf(); Integer integer = 1; // 自动拆箱 int int111 = integer;
自动装箱的内存复用
自动装箱时,对于Integer var = 数值 ,如果var指向的对象在-128 至 127 范围内的赋值时,生成的Integer实例化对象是由 IntegerCache.cache() 方法产生,它会复用已有对象。和String的串池操作是一个道理,cache()方法会将位于-128~127范围内产生的Integer对象入池,下次使用的时候,从缓冲区中拿去,就不会在创建了。可以节省内存的使用!
所以,在这个数值区间内的 Integer对象的栈指向(属性名) 可以直接使用==进行判断,因为值相同,指向的就是同一片区域。
但是这个区间之外的所有数据,自动装箱都会在堆上产生实例化,并不再复用已有对象,这是一个大坑,为了避免这个问题,推荐使用 equals 方法进行Integer的判断。
对于所有数值型的包装类来说,都会涉及到上面这种问题,一定要多加注意。
而对于手动装箱,即采用new进行包装类创建时,不会发生内存复用,因为new关键字每次使用,都会开辟新的空间,这和String采用构造方法创建字符串不入串池池相对应。
另外:
所有的相同类型的包装类对象之间值的比较,全部使用equals()方法。