为什么需要包装类?
首先,Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,将每个基本数据类型设计一个对应的类进行代表,这种方式增强了Java面向对象的性质。
其次,如果仅仅有基本数据类型,那么在实际使用时将存在很多的不便,很多地方都需要使用对象而不是基本数据类型。比如,在集合类中,我们是无法将int 、double等类型放进去的,因为集合的容器要求元素是Object类型。而包装类型的存在使得向集合中传入数值成为可能,包装类的存在弥补了基本数据类型的不足。
此外,包装类还为基本类型添加了属性和方法,丰富了基本类型的操作。如当我们想知道int取值范围的最小值,我们需要通过运算,如下面所示,但是有了包装类,我们可以直接使用Integer.MAX_VALUE即可。
//求int的最大值
int max = 0;
int flag = 1;
for (int i=0; i<31; i++) {
max += flag;
flag = flag << 1;
}
System.out.println(max +" "+ Integer.MAX_VALUE); //2147483647 2147483647
包装类的2种主要用途:
java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类。
- 作为 和基本数据类型对应的类 类型存在,方便涉及到对象的操作。
- 包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。
为什么要保留基本数据类型?
我们都知道在Java语言中,用new关键字创建的对象是存储在堆里的,我们通过栈中的引用来使用这些对象,所以,对象本身来说是比较消耗资源的。对于经常用到的类型,如int等,如果我们每次使用这种变量的时候都需要new一个对象的话,就会比较笨重了。所以,Java提供了基本数据类型,这种数据的变量不需要使用new在堆上创建,而是直接在栈内存中存储,因此会更加高效。
包装类(wrapper class/ラッパークラス),自动拆箱,自动装箱,基本类型与字符串之间的转换
Java数据类型
Java常量
类型 | 含义 | 数据举例 |
---|---|---|
整数常量 | 所有的整数 | 0,1, 567, -9 |
小数常量 | 所有的小数 | 0.0, -0.1, 2.55 |
字符常量 | 单引号引起来,只能写一个字符,必须有内容 | ‘a’ , ’ ', ‘好’ |
字符串常量 | 双引号引起来,可以写多个字符,也可以不写 | “A” ,“Hello” ,“你好” ,“” |
布尔常量 | 只有两个值(流程控制中讲解) | true , false |
空常量 | 只有一个值(引用数据类型中讲解) | null |
package ArrayTest;
public class Array10 {
char a;
public static void main(String[] args) {
new Array10().re();
}
public void re(){
System.out.println("a = " + a);
System.out.println(a==0);
System.out.println(a=='\u0000');
System.out.println(a==null);//编译报错
}
}
‘\u0000’~'\UFFFF’是什么意思
范围:0到65535。它不过对应的是unicode的编码值,即全球语言统一编码。
\u开头的是一个Unicode码的字符,每一个’\u0000’都代表了一个空格。
通常中文在的显示都是被转化为Unicode显示的。
Java变量
- 基本数据类型:整数、浮点数、字符、布尔
- 引用数据类型: 类、数组、接口
数据类型 | 关键字 | 内存占用 | 取值范围 |
---|---|---|---|
字节型 | byte | 1个字节 | -128 至 127 |
短整型 | short | 2个字节 | -32768 至 32767 |
整型 | int | 4个字节 | -231 至 231-1 |
长整型 | long | 8个字节 | -263 至 263-1 |
单精度浮点数 | float | 4个字节 | 1.4013E-45 至 3.4028E+38 |
双精度浮点数 | double | 8个字节 | 4.9E-324 至 1.7977E+308 |
字符型 | char | 2个字节 | 0 至 216-1 |
布尔类型 | boolean | 1个字节 | true,false |
Java提供的包装类
class IntDemo {
private int num;
public IntDemo(int num) {
this.num = num;
}
public int intValue() {
return this.num;
}
}
虽然上面的IntDemo类能实现一些辅助功能,而且可以支持泛型反射等功能,但是如果如果每次使用都自己封装这么一个类的话,就太繁琐了。所以,java为我们提供了基本数据类型的包装类,这些包装类分为两类,一种是对象型包装类,不继承任何其他类(Object的直接子类),另一种是数值型包装类,继承于Number类。
对象型(Object 的直接子类)包装类:
// boolean的包装类
public final class Boolean implements java.io.Serializable, Comparable<Boolean>
// char的包装类
public final class Character implements java.io.Serializable, Comparable<Character>
数值型(继承了Number类)包装类:
// byte的包装类
public final class Byte extends Number implements Comparable<Byte>
// short的包装类
public final class Short extends Number implements Comparable<Short>
// int的包装类
public final class Integer extends Number implements Comparable<Integer>
// long的包装类
public final class Long extends Number implements Comparable<Long>
// float的包装类
public final class Float extends Number implements Comparable<Float>
// double的包装类
public final class Double extends Number implements Comparable<Double>
Boolean和Character两个类就是正常的属性方法封装,但是数值型的包装类继承了一个Number类。
public abstract class Number implements java.io.Serializable
其中定义的方法如下:
Java装箱拆箱
-
装箱:从基本类型转换为对应的包装类对象。int→Integer
-
拆箱:从包装类对象转换为对应的基本类型。Integer→int
手动装箱拆箱
// 装箱
Integer integer1 = new Integer(1);
//或者
Integer i2 = Integer.valueOf(4);
// 拆箱
int integer2 = integer1.intValue();
自动装箱拆箱
由于我们经常要做基本类型与包装类之间的转换,sun公司发现这样写比较麻烦,于是从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。
自动装箱:可以直接把一个基本类型的数据赋值给自己对应的包装类型。
自动拆箱:可以直接把一个包装类型的数据赋值给自己对应的基本类型。
// 自动装箱
Integer integer1 = 1;
Integer i = 4;//相当于i = Integer.valueOf(4);
// 自动拆箱
int integer2 = integer1;
i = i + 5;//相当于i.intValue() + 5;
基本类型与字符串之间的转换
基本类型转字符串
- 可以直接使用+号
- 使用String类中的valueOf()方法
- 使用对应的包装类中重载的toString()方法
byte、short、char–>int–>long–>float–>double
public class Demo01 {
public static void main(String[] args) {
//使用+完成基本数据类型到字符串的转换
int x=123;
String s=x+"";
//使用String类中的valueOf
int i = 1;
String s1 = String.valueOf(1.2);
String s2 = String.valueOf(true);
String s3 = String.valueOf(i);
String s0 = String.valueOf('a');
int j = 2;
byte x = 2;
short y = 2;
long l =2;
//使用对应的包装类中重载的toString方法
String s8 = Byte.toString(x);
String s9 = Byte.toString((byte) 2);
String s13 = Short.toString(y);
String s12 = Short.toString((short) 3);
String s14 = Long.toString(l);
}
}
字符串转换成对应的基本类型
- 字符串转成基本类型使用包装类中的parseXxxx方法。
public static int parseInt(String s):将字符串参数转换为对应的int基本类型
-
后期学习中遇到和parse相关的函数,都是把字符串解析成其他的数据。
-
使用parseXxxx方法把一个字符串转成基本数据类型的时候,前提是这个字符串一定能够被转成对应的基本类型,否则会发生NumberFormatException异常。
package com.web;
public class Test43 {
public static void main(String[] args) {
//字符串转成基本类型使用包装类中的parseXxxx方法
int num = Integer.parseInt("100");
byte b1 = Byte.parseByte("2");
byte b3 = Byte.parseByte("a");
short sh = Short.parseShort("2");
}
}