为什么要存在包装类
基本类型也叫内置类型,是java中不同于类的特殊类型。
拿集合举例,说明为什么需要包装类
早期的集合,大量使用Object类型来支持多种不同的引用数据类型,这导致了一个类型丢失的问题
自从引入了泛型,使得集合中的元素可以保证自己的类型不再丢失,虽然这样可能会导致同一个list集合不再能存储多种不同的引用数据类型,只能存放菱形语法标识的类型数据,但是同一个list存放多个不同类型的数据的场景是很少的,而且集合在创建时也可以不指定泛型,默认类型就是Object,完全满足了所有引用类型的场景
基本数据类型从被集合抛弃,到被泛型抛弃,但是基本数据类型却是开发中使用最多的,开发者只能自己写一个int的容器,float的容器…可能一下子就要写8个容器,非常的不方便,如果将int、float、double封装成类似于String类型的数据类型,是否就可以满足基本数据类型需要使用集合和泛型的场景,答案是可以的
因此存在包装类的原因就是为了满足一些基本数据类型被抛弃的场景,当然,在不涉及到基本类型必须转换为包装类的情况下,尽量使用基本数据类型,因为这是更底层的数据类型更高效,且对象本身就更浪费资源
包装类
特点:具有类的特点,可以调用相应类的方法,可以被泛型接受 包装类是基于8种基本类型而封装的8个对象的包装类
包装类 | 基本数据类型 |
---|---|
Byte | byte |
Short | short |
Integer | int |
Long | long |
Float | float |
Double | double |
Character | char |
Boolean | boolean |
装箱(boxing)
装箱分为两种方式,手动装箱和自动装箱
-
手动装箱也有两种方式
-
通过new一个包装类,在构造器中传参即可装箱
-
通过包装类的静态方法valueOf()方法
-
-
自动装箱则将基本数据类型的值赋值给包装类对象
public class Boxing {
@Test
public void boxingInteger() {
int i=10;
//手动装箱
Integer w=new Integer(i);
Integer integer = Integer.valueOf(i);
//自动装箱
Integer e=i;
}
@Test
public void boxingLong() {
long l = 10L;
//手动装箱
Long w = new Long(l);
Long long_ = Long.valueOf(l);
//自动装箱
Long e = l;
}
@Test
public void boxingFloat() {
float f = 10.13f;
//手动装箱
Float w = new Float(f);
Float float_ = Float.valueOf(f);
//自动装箱
Float e = f;
}
@Test
public void boxingDouble() {
double d = 10.30;
//手动装箱
Double w = new Double(d);
Double double_ = Double.valueOf(d);
//自动装箱
Double e = d;
}
@Test
public void boxingBoolean() {
boolean b = true;
//手动装箱
Boolean w = new Boolean(b);
Boolean boolean_ = Boolean.valueOf(b);
//自动装箱
Boolean e = b;
}
@Test
public void boxingCharacter() {
char c = 'a';
//手动装箱
Character w = new Character(c);
Character character = Character.valueOf(c);
//自动装箱
Character e = c;
}
@Test
public void boxingByte() {
byte b = 10;
//手动装箱
Byte w = new Byte(b);
Byte byte_ = Byte.valueOf(b);
//自动装箱
Byte e = b;
}
@Test
public void boxingShort() {
short s = 10;
//手动装箱
Short w = new Short(s);
Short short_ = Short.valueOf(s);
//自动装箱
Short e = s;
}
}
拆箱(unboxing)
拆箱也分为两种:手动拆箱和自动拆箱
-
手动拆箱使用包装类的方法
xxxValue()
方法 -
自动拆箱则直接将包装类的值赋值给基本数据类型
public class UnBoxing {
@Test
public void UnBoxingInteger(){
Integer i = 20;
int a=i;//自动拆箱
int b=i.intValue();//手动拆箱
}
@Test
public void UnBoxingLong(){
Long i = 20L;
long a=i;//自动拆箱
long b=i.longValue();//手动拆箱
}
@Test
public void UnBoxingFloat(){
Float i = 20F;
float a=i;//自动拆箱
float b=i.floatValue();//手动拆箱
}
@Test
public void UnBoxingDouble(){
Double i = 20D;
double a=i;//自动拆箱
double b=i.doubleValue();//手动拆箱
}
@Test
public void UnBoxingShort(){
Short i = 20;
short a=i;//自动拆箱
short b=i.shortValue();//手动拆箱
}
@Test
public void UnBoxingByte() {
Byte i = 20;
byte a = i;//自动拆箱
byte b = i.byteValue();//手动拆箱
}
@Test
public void UnBoxingCharacter() {
Character i = 'a';
char a = i;//自动拆箱
char b = i.charValue();//手动拆箱
}
@Test
public void UnBoxingBoolean() {
Boolean i = true;
boolean a = i;//自动拆箱
boolean b = i.booleanValue();//手动拆箱
}
}
自动装箱和拆箱的原理
自动装箱的原理:
public static void main(String[]args){
Integer integer=1; //装箱
int i=integer; //拆箱
}
反编译后代码为:
public static void main(String[]args){
Integer integer=Integer.valueOf(1);
int i=integer.intValue();
}
自动装箱都是通过包装类的valueOf()
方法来实现的,自动拆箱都是通过包装类对象的xxxValue()
方法来实现的
包装类的缓存机制
如果数值在[-128,127]之间则返回指向IntegerCache.cache中已经存在的对象;否则创建一个新对象Integer、Sort、Byte、Character、Long这几个类的valueOf方法是类似的
Integer、Sort、Byte、Long包装类的缓存范围[-128,127]
Character包装类缓存范围[0,127]
Double、Float的valueOf方法的实现是类似的,因为值不是离散的是连续的,不能使用缓存保存,所以没有范围
基本类型、包装类和String的转换
String《=》基本数据类型
基本数据类型 =》String
缺少byte和short,是因为byte和shot都能自动转换为int类型,因此都可以使用valueOf(int i)方法
byte b=1;
int i = b;
short st = 2;
int j = st;
String s = String.valueOf(b);
String =》基本数据类型
-
使用该基本数据类型对应的包装类调用
paseXxx()
方法 -
自动拆箱
String str="123"; int k = Integer.parseInt(str);
-
字符串转换为整型或浮点型,字符串必须也是数字;否则报错
java.lang.NumberFormatException: For input string: "你好"
-
字符串转换为boolean类型,字符串必须为true或false,否则除了"true"转换为true,其他都是false
-
字符串转char类型不能使用上述方法
String类型转char类型,只能是转成char数组
String str="true";
char[] c = new char[str.length()];
for (int i = 0; i < str.length(); i++) {
c[i]=str.charAt(i);
System.out.println(c[i]);
}
String《=》包装类
包装类 =》String
包装类转换String有两种方式
-
拼接的方式
Integer i=50 String str=i+"";
-
调用toString()方法
Integer i=50 String str=i.toString(); String str1=Integer.toString(i);
String =》包装类
使用该基本数据类型对应的包装类调用paseXxx()
方法
String str="123";
Integer k = Integer.parseInt(str);
Character类型的依旧参考String类型转char类型
包装类《=》基本数据类型
也就是装箱和拆箱,不再赘述