包装类
Java提供的8种基本数据类型不支持面向对象的编程机制,因此,Java为它们提供了包装类(wrapper class),为这8种基本数据类型分别定义了相应的引用类型。
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
包装类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值。同时,包装器类还是final
的,因此不能派生它们的子类。
1. 自动装箱与自动拆箱
为了方便包装类的使用,JDK1.5 开始提供了自动装箱和自动拆箱的功能。
- 自动装箱:可以把一个基本类型变量直接赋给对应的包装类变量,或者赋给
Object
变量; - 自动拆箱:与装箱相反,允许把包装类对象直接赋给一个对应的基本类型变量。
public class AutoBoxingUnboxing {
public static void main(String[] args) {
// 直接把一个基本类型变量赋给Integer对象
Integer inObj = 5;
// 直接把一个boolean类型变量赋给一个Object类型的变量
Object boolObj = true;
// 直接把一个Integer对象赋给int类型的变量
int it = inObj;
if (boolobj instanceof Boolean) {
// 先把Object对象强制类型转换为Boolean类型,再赋给boolean变量
boolean b = (Boolean)boolObj;
System.out.println(b);
}
}
}
由于每个值分别包装在对象中,所以ArrayList<Integer>
的效率远远低于int[]
数组。
自动装箱规范要求boolean
、byte
、char
不超过 127,介于 -128 和 127 之间的 short
和 int
被包装到固定的对象中。
最后强调一下,装箱和拆箱是编译器要做的工作,而不是虚拟机。
从字节码中可知,装箱过程是通过调用包装器的
valueOf
方法实现的,而拆箱过程是通过调用包装器的xxxValue
方法实现的。
2. 包装类的比较
2.1 包装类实例与基本数值类型的比较
虽然包装类型的变量是引用数据类型,但包装类的实例可以与数值类型的值进行比较,这种比较是直接取出包装类实例所包装的数值来进行的。
Integer a = Integer.valueOf(6);
// 输出true
System.out.println(a > 5.0);
2.2 两个包装类实例之间的比较
注意,若两个包装类的实例进行比较,由于包装类的实例实际上是引用类型,因此只有两个包装类引用指向同一个对象时才会返回true
System.out.println(Integer.valueOf(128) == Integer.valueOf(128)); // false
2.3 特殊情况——缓存
特殊地, 由于java.lang.Integer
源码中对-128~127的整数自动装箱为Integer
实例,并放入一个cache数组缓存起来, 以下输出为 true
System.out.println(Integer.valueOf(127) == Integer.valueOf(127)); // true
2.4 包装类的静态方法compare(Xxx val1, Xxx val2)
Java还为所有的包装类提供了一个静态的compare(xxx val1, xxx val2)
方法,可以用来比较两个基本类型值的大小,包括比较两个boolean
类型值(此时true > false)
System.out.println(Boolean.compare(true, false)); //输出1
System.out.println(Boolean.compare(true, true)); //输出0
System.out.println(Boolean.compare(false, true)); //输出-1
3. 基本类型变量与字符串之间的转换
字符串类型的值->基本类型的值:
利用包装类提供的
parseXxx(String s)
静态方法(除Character
外所有包装类都提供该方法)利用包装类提供的
valueOf(String s)
静态方法
基本类型的值->字符串类型的值:
- String类提供了多个重载
valueOf()
方法,用于将基本类型变量转换成字符串 - 将基本类型变量和
""
进行连接运算,系统会自动把基本类型变量转换成字符串
public class Primitive2String {
public static void main(String[] args) {
String intStr = "123";
// 把一个特定字符串转换成int变量
int it1 = Integer.parseInt(intStr);
int it2 = Integer.valueOf(intStr);
System.out.println(it2);
String floatStr = "4.56";
// 把一个特定字符串转换成float变量
float ft1 = Float.parseFloat(floatStr);
float ft2 = Float.valueOf(floatStr);
System.out.println(ft2);
// 把一个float变量转换成String变量
String ftStr = String.valueOf(2.345f);
System.out.println(ftStr);
// 把一个double变量转换成String变量
String dbStr = String.valueOf(3.344);
System.out.println(dbStr);
// 把一个boolean变量转换成String变量
String boolStr = String.valueOf(true);
System.out.println(boolStr.toUpperCase());
}
}
4. Java8的增强
Java 8再次增强了包装类的功能,其中之一是支持无符号算术运算
- 为整型包装类
Integer, Long
提供的无符号运算支持:static String toUnsignedString(int/long i)
static String toUnsignedString(int/long i, int radix)
:radix指定进制static xxx parseUnsignedXxx(String s)
:将字符串解析成无符号整数。static xxx parseUnsignedXxx(String s, int radix)
static int compareUnsigned(xxx x, xxx y)
:将x、y两个整数转换为无符号整数后比较大小。- 当调用类为
Integer
时,xxx
代表int
; - 当调用类为
Long
时,xxx
代表long
。
- 当调用类为
static long divideUnsigned(long dividend, long divisor)
:将x、y转换为无符号整数后计算它们相除的商。static long remainderUnsigned(long dividend, long divisor)
:将x、y转换为无符号整数后计算它们相除的余数。
- 为
Byte, Short
提供了toUnsignedInt(xxx x)
,toUnsignedLong(yyy x)
两个方法,用于将指定byte
或short
类型的变量或值转换成无符号的int
或long
值