在Java的世界里,万物皆对象——但基本数据类型除外。为了解决基本类型无法参与面向对象操作的困境,Java提供了包装类(Wrapper Classes)。让我们通过一个表格快速了解基本类型及其对应的包装类:
基本数据类型 | 包装类 | 字节大小 | 默认值 |
---|---|---|---|
byte | Byte | 1 | 0 |
short | Short | 2 | 0 |
int | Integer | 4 | 0 |
long | Long | 8 | 0L |
float | Float | 4 | 0.0f |
double | Double | 8 | 0.0d |
char | Character | 2 | '\u0000' |
boolean | Boolean | 1 | false |
将基本数据类型转换为对应的包装类对象
// 手动装箱(JDK1.5之前的方式)
Integer manualBoxing = Integer.valueOf(100);
// 自动装箱(JDK1.5+)
Integer autoBoxing = 100;
将包装类对象转换为对应的基本数据类型
Integer numObj = 200;
// 手动拆箱
int manualUnboxing = numObj.intValue();
// 自动拆箱
int autoUnboxing = numObj;
Java编译器在编译时会自动插入转换代码:
// 编译前代码
Integer boxed = 42;
int unboxed = boxed;
// 编译后等效代码
Integer boxed = Integer.valueOf(42);
int unboxed = boxed.intValue();
Integer nullable = null;
// 下面这行代码会抛出NullPointerException
int dangerous = nullable;
Java对部分包装类对象进行了缓存优化:
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true (使用缓存)
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false (新建对象)
在循环中使用自动装箱会带来性能开销:
// 低效写法:每次循环都会创建Integer对象
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i; // 自动装箱
}
// 优化写法:使用基本类型
long sum = 0L;
// 只能存储对象,不能存储基本类型
List numbers = new ArrayList<>();
numbers.add(1); // 自动装箱
numbers.add(2);
int first = numbers.get(0); // 自动拆箱
// 泛型类示例
public class Box {
private T value;
public void set(T value) { this.value = value; }
public T get() { return value; }
}
Box intBox = new Box<>();
intBox.set(100); // 自动装箱
int val = intBox.get(); // 自动拆箱
// 处理可能为null的数据库整数字段
Integer age = resultSet.getInt("age");
if (age != null) {
System.out.println("年龄:" + age);
} else {
System.out.println("年龄信息缺失");
}
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;
System.out.println(a == b); // true
System.out.println(c == d); // false
解析:Java对-128到127之间的Integer对象进行了缓存
Integer x = new Integer(300);
Integer y = new Integer(300);
System.out.println(x == y); // false(比较对象引用)
System.out.println(x.equals(y)); // true(比较对象值)
Double total = 0.0;
for (int i = 0; i < 1000000; i++) {
total += i;
}
解析:每次+=操作都会发生拆箱和装箱操作,应改用基本类型double
装箱:基本类型 → 包装类对象(自动/手动)
拆箱:包装类对象 → 基本类型(自动/手动)
最佳实践:
在循环中避免使用自动装箱
比较包装类对象使用equals()而非==
警惕包装类可能的null值导致的NPE
了解-128~127的Integer缓存机制