一、包装类概述
1、为什么需要包装类
Java并不是纯面向对象的语言。Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。基本数据类型有它的优势:性能(效率高,节省空间)。
在实际使用中经常需要将基本数据类型转成对象,这时就需要将基本数据类型数据转化为对象。
2、包装类
Java 提供了两个类型系统:基本类型与引用类型。
使用基本类型在于效率,然后很多情况,需要创建对象使用,因为对象可以做更多的功能。
基本类型对应的包装类:
基本类型 | 对应的包装类(位于java.lang包中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
二、装箱与拆箱
基本类型与对应包装类对象之间,来回转换的过程称为“装箱”与“拆箱”。
- 装箱:从基本类型转换到对应的包装类对象;
- 拆箱:从包装类对象转换到对应的基本类型。
1、装箱:把基本类型的数据,包装到包装类中(基本类型的数据 -> 包装类)
构造方法:
Integer(int value) 构造一个新分配的 Integer 对象,它表示指定的 int 值。
Integer(String s) 构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。传递的字符串,必须是基本类型的字符串,否则会抛出异常 如:"100" 正确; "a" 抛出NumberFormatException数字格式化异常
静态方法:
static Integer valueof(int i):返回一个表示指定的 int 值的 Integer 实例。
static Integer valueof(String a):返回保存指定的 String 的值的 Integer 对象。
2、拆箱:在包装类中取出基本类型的数据(包装类->基本类型的数据)
成员方法:
int intValue() 以 int 类型返回该 Integer 的值。
Demo:
// 装箱
//构造方法
Integer in1 = new Integer(1);
Integer in2 = new Integer("1"); //静态方法
Integer in3 = Integer.valueOf(1);
Integer in4 = Integer.valueOf("1"); // 拆箱
int i = in1.intValue();
三、自动装箱(auto_boxing)与自动拆箱(unboxing)
由于经常要做基本类型与包装类之间的转换,从 Java5(JDK1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。
自动装箱:当把基本数据类型的值,赋值给包装类的变量时,就会自动装箱。
自动拆箱:把包装类的对象赋值给对应的基本数据类型的变量时,就会自动拆箱。
注意:自动装箱与拆箱都是只发送在对应类型上。
Demo:
Integer i = 3; // 自动装箱。相当于Integer i = Integer.valueOf(3);
i = i + 5; // 等号右边:将 i 对象转成基本数值(自动拆箱) i.intValue() + 5;
// 加法运算完成后,再次装箱,把基本数值转成对象。
四、包装类的 API
1、基本类型转换为字符串 String
a、基本类型的值 + "" 最简单的方法(最常用)
b、包装类的静态方法 toString(参数)
static String toString(int i) 返回一个表示指定整数的 String 对象。
c、String 类的静态方法 valueOf(参数)
static String valueOf(int i) 返回 int 参数的字符串表示形式。
2、字符串(String)转换为基本类型
除了 Character 类之外,其他所有包装类都具有 parseXxx 静态方法可以将字符串参数转换为对应的基本类型。
public static byte parseByte(String s):将字符串参数转换为对应的byte基本类型。
public static short parseShort(String s):将字符串参数转换为对应的short基本类型。
public static int parseInt(String s):将字符串参数转换为对应的int基本类型。
public static long parseLong(String s):将字符串参数转换为对应的long基本类型。
public static float parseFloat(String s):将字符串参数转换为对应的float基本类型。
public static double parseDouble(String s):将字符串参数转换为对应的double基本类型。
public static boolean parseBoolean(String s):将字符串参数转换为对应的boolean基本类型。
也可以使用 valueOf(xx) 方法,将字符串转换为基本类型。
static Integer valueOf(String s) 返回保存指定的 String 的值的 Integer 对象。
注意:如果字符串参数的内容无法正确转换为对应的基本类型,则会抛出java.lang.NumberFormatException
异常。
3、进制转换(Integer 类型)
System.out.println(Integer.toBinaryString(10));//转为二进制
System.out.println(Integer.toOctalString(10));//转为八进制
System.out.println(Integer.toHexString(10));//转为十六进制
4、常量值(Byte,Short,Integer,Long,Float,Double)
MAX_VALUE:代表范围内的最大值;MIN_VALUE:代表范围内的最小值
Integer.MIN_VALUE
Integer.MAX_VALUE
5、转换大小写(Character对象)
Character.toUpperCase('a')
Character.toLowerCase('T')
五、包装类对象的缓存问题
在编程时大量需要值在-128到127范围之间的Integer对象。如果只能通过new来创建,需要在堆中开辟大量值一样的Integer对象。这是相当不划算的,IntegerCache.cache很好的起到了缓存的作用。
对于自动装箱这种情况,Byte,Short,Integer,Long:都有缓存对象,范围 -128~127;Character 缓存对象范围 0~127;Boolean 缓存对象范围:true,false。
Float,Double没有缓存对象。
Demo1:
(1)
int a = 1;
int b = 1;
System.out.println(a == b);//true (2)
int c = 130;
int d = 130;
System.out.println(c == d);//true (3)
//自动装箱
Integer a = 1;
Integer b = 1;
System.out.println(a == b);//true a == b比较的也是地址值 a和b指向的是同一个缓存的常量对象 (4)
Integer c = 130;
Integer d = 130;
System.out.println(c == d);//false c == d比较的也是地址值 c和d都是在堆中新建的Integer对象 (5)
Integer a = 1;
Double b = 1.0;
Long c = 1L;
long d = 1L; //System.out.println(a == b);//无法比较,因为对象比较地址,必须是同一种类型或有父子类关系
//System.out.println(a == c);//无法比较,因为对象比较地址,必须是同一种类型或有父子类关系 System.out.println(a == d);// true 因为d是基本数据类型,a才会自动拆箱, int 与 long 比较,可以比较 (6)
Double d1 = 1.0;
Double d2 = 1.0;
System.out.println(d1 == d2);//false Float与 Double没有缓存对象 (7)
Character c1 = '0';//ASCII码,Unicode码:48
Character c2 = '0';
System.out.println(c1 == c2);//true Character c3 = '中';
Character c4 = '中';
System.out.println(c3 == c4);//false
Demo2:
Integer i = 1;
Integer j = 1;
System.out.println(i == j);//true Integer i = 128;
Integer j = 128;
System.out.println(i == j);//false Integer i = new Integer(1);//新new的在堆中
Integer j = 1;//这个用的是缓冲的常量对象,在方法区
System.out.println(i == j);//false Integer i = new Integer(1);//新new的在堆中
Integer j = new Integer(1);//另一个新new的在堆中
System.out.println(i == j);//false Integer i = new Integer(1);
int j = 1;
System.out.println(i == j);//true,凡是和基本数据类型比较,都会先拆箱,按照基本数据类型的规则比较