Java 的包装类(Wrapper Classes)作用

Java 的 包装类(Wrapper Class) 主要用于将 基本数据类型(primitive types) 转换为 对象类型(reference types),它们提供了额外的方法,并且在某些情况下是必需的,比如在 集合框架(如 ArrayList 中存储数据。


1. Java 包装类有哪些?

Java 为每种基本数据类型提供了对应的包装类:

基本类型(Primitive Type) 包装类(Wrapper Class)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

2. 为什么需要包装类?

(1) 在集合(ArrayListHashMap 等)中存储基本类型

Java 集合框架(如 ArrayListHashMap不支持基本类型,必须使用对象类型。
例如,ArrayList<int> 是非法的,必须使用 ArrayList<Integer>

错误示例(不能使用 int):

java

复制编辑

ArrayList<int> list = new ArrayList<>(); // ❌ 错误!

正确示例(使用 Integer):

java

复制编辑

ArrayList<Integer> list = new ArrayList<>(); list.add(10); // 自动装箱 list.add(20); System.out.println(list.get(0)); // 输出 10


(2) null 处理

基本类型(如 intdouble不能赋值 null,但包装类可以:

java

复制编辑

Integer a = null; // ✅ 合法 int b = null; // ❌ 错误(基本类型不能为 null)

这在 数据库操作JSON 解析 时很常见,比如 null 表示数据缺失。


(3) 提供了额外的方法

包装类提供了许多有用的方法,比如:

  • Integer.parseInt(String) 将字符串转换为 int
  • Double.parseDouble(String) 将字符串转换为 double
  • Integer.toHexString(int) 将整数转换为十六进制字符串
  • Boolean.valueOf(String) 解析布尔值

java

复制编辑

String str = "123"; int num = Integer.parseInt(str); // 将字符串 "123" 转换为 int System.out.println(num * 2); // 输出 246


(4) 自动装箱(Autoboxing)和自动拆箱(Unboxing)

Java 5 引入了自动装箱/拆箱,减少了手动转换的麻烦。

自动装箱(Autoboxing)

基本类型 包装类 自动转换

java

复制编辑

Integer num = 10; // 相当于 Integer num = Integer.valueOf(10);

自动拆箱(Unboxing)

包装类 基本类型 自动转换

java

复制编辑

int x = num; // 相当于 int x = num.intValue();

示例:

java

复制编辑

ArrayList<Integer> list = new ArrayList<>(); list.add(10); // 自动装箱 int value = list.get(0); // 自动拆箱 System.out.println(value + 1); // 输出 11


(5) 类型转换

包装类允许不同类型之间的转换:

java

复制编辑

int i = 100; String str = Integer.toString(i); // int → String int j = Integer.parseInt(str); // String → int


3. 包装类和基本类型的性能

包装类的对象在 堆内存(Heap) 分配,而基本类型通常在 栈内存(Stack) 中。
因此:

  • 基本类型性能更好,占用内存更少
  • 包装类需要额外的内存和时间,频繁使用时可能影响性能。

示例:包装类和基本类型性能对比

java

复制编辑

public class Test { public static void main(String[] args) { long startTime, endTime; // 测试基本类型 int startTime = System.nanoTime(); int sum1 = 0; for (int i = 0; i < 1000000; i++) { sum1 += i; } endTime = System.nanoTime(); System.out.println("基本类型 int 耗时: " + (endTime - startTime) + " ns"); // 测试包装类 Integer startTime = System.nanoTime(); Integer sum2 = 0; for (int i = 0; i < 1000000; i++) { sum2 += i; // 这里涉及大量的装箱和拆箱 } endTime = System.nanoTime(); System.out.println("包装类 Integer 耗时: " + (endTime - startTime) + " ns"); } }

💡 结论:包装类由于装箱/拆箱,性能比基本类型差很多,因此在性能敏感的场景下,应尽量使用基本类型


4. 小结

用途 包装类(Wrapper Class)作用
集合存储 ArrayList<Integer> 不能存 int,只能存 Integer
null 处理 包装类可以存 null,基本类型不行
提供方法 Integer.parseInt()Double.toString()
自动装箱/拆箱 Integer num = 10; (装箱)int x = num; (拆箱)
类型转换 String → intint → String
性能考虑 基本类型更快,占用内存更少

Integer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.ArrayList;  
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;

public class Javastudy {
public static void main(String[] args) { // 验证字符串是否是一个邮箱地址
ArrayList<String> lst = new ArrayList<>();
lst.add("12");
lst.add("13");

int sum = 0;
for (int i = 0; i < 2; i++) {
sum += Integer.parseInt(lst.get(i));
System.out.println(sum);
}

String str = Integer.toString(456); // toString把数据转化为String类型
}
}

主要出现的功能(以Int为例子):

  • intValue()
  • parseInt(String) 返回该string的int值.

BigInteger

Java中的BigInteger范围

在Java中,BigInteger类是用于处理超出标准数据类型(如intlong)范围的大整数的。BigInteger类位于java.math包中,它提供了一系列方法来进行大整数的算术运算,比如加法、减法、乘法和除法等。BigInteger的一个关键特点是它可以表示非常大的数值,理论上只受限于计算机的内存大小。

要创建一个BigInteger实例,你可以使用其构造函数传入一个字符串表示的数值,例如:

BigInteger bi = new BigInteger(“1234567890”);

然后,你可以使用BigInteger提供的方法来执行各种算术操作。例如,要执行加法,你可以使用add方法:

1
2
3
BigInteger i1 = new BigInteger("1234567890");
BigInteger i2 = new BigInteger("12345678901234567890");
BigInteger sum = i1.add(i2); // 结果为12345678902469135780

转换为基本数据类型

尽管BigInteger可以表示非常大的数值,但有时候我们需要将其转换为基本数据类型,如longBigInteger提供了一系列方法来进行这种转换,例如longValue()longValueExact()longValue()方法会尝试将BigInteger的值转换为long类型,如果数值超出了long的范围,它会返回一个近似值。而longValueExact()方法在转换结果超出long范围时会抛出ArithmeticException异常。

使用BigInteger的一个缺点是其速度相对于原生类型(如intlong)较慢,因为BigInteger的运算是通过软件模拟实现的。因此,在性能敏感的应用中,如果可能,最好还是使用原生类型。

示例

以下是一个使用BigInteger的简单示例,它演示了如何创建BigInteger对象,执行幂运算,以及如何处理超出long范围时的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.math.BigInteger;

public class Main {
public static void main(String[] args) {
BigInteger bi = new BigInteger("1234567890");
System.out.println(bi.pow(5)); // 输出: 2867971860299718107233761438093672048294900000

BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 输出: 123456789000
try {
System.out.println(i.multiply(i).longValueExact()); // 将抛出 java.lang.ArithmeticException
catch (ArithmeticException e) {
System.out.println("BigInteger out of long range");
}
}
}

在这个示例中,我们创建了一个BigInteger对象,并计算了它的五次方。然后,我们尝试将一个大BigInteger值转换为long类型,当转换结果超出long的范围时,捕获并处理了ArithmeticException异常。

总的来说,BigInteger是一个非常强大的类,它允许Java程序员处理超出标准整数类型范围的数值。不过,需要注意的是,使用BigInteger可能会牺牲一些性能。