Java包装类
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) 在集合(ArrayList、HashMap 等)中存储基本类型
Java 集合框架(如 ArrayList、HashMap)不支持基本类型,必须使用对象类型。
例如,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 处理
基本类型(如 int、double)不能赋值 null,但包装类可以:
java
复制编辑
Integer a = null; // ✅ 合法 int b = null; // ❌ 错误(基本类型不能为 null)
这在 数据库操作 或 JSON 解析 时很常见,比如 null 表示数据缺失。
(3) 提供了额外的方法
包装类提供了许多有用的方法,比如:
Integer.parseInt(String)将字符串转换为intDouble.parseDouble(String)将字符串转换为doubleInteger.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 → int,int → String |
| 性能考虑 | 基本类型更快,占用内存更少 |
Integer
1 | import java.util.ArrayList; |
主要出现的功能(以Int为例子):
- intValue()
- parseInt(String) 返回该string的int值.
BigInteger
Java中的BigInteger范围
在Java中,BigInteger类是用于处理超出标准数据类型(如int、long)范围的大整数的。BigInteger类位于java.math包中,它提供了一系列方法来进行大整数的算术运算,比如加法、减法、乘法和除法等。BigInteger的一个关键特点是它可以表示非常大的数值,理论上只受限于计算机的内存大小。
要创建一个BigInteger实例,你可以使用其构造函数传入一个字符串表示的数值,例如:
BigInteger bi = new BigInteger(“1234567890”);
然后,你可以使用BigInteger提供的方法来执行各种算术操作。例如,要执行加法,你可以使用add方法:
1 | BigInteger i1 = new BigInteger("1234567890"); |
转换为基本数据类型
尽管BigInteger可以表示非常大的数值,但有时候我们需要将其转换为基本数据类型,如long。BigInteger提供了一系列方法来进行这种转换,例如longValue()和longValueExact()。longValue()方法会尝试将BigInteger的值转换为long类型,如果数值超出了long的范围,它会返回一个近似值。而longValueExact()方法在转换结果超出long范围时会抛出ArithmeticException异常。
使用BigInteger的一个缺点是其速度相对于原生类型(如int和long)较慢,因为BigInteger的运算是通过软件模拟实现的。因此,在性能敏感的应用中,如果可能,最好还是使用原生类型。
示例
以下是一个使用BigInteger的简单示例,它演示了如何创建BigInteger对象,执行幂运算,以及如何处理超出long范围时的情况:
1 | import java.math.BigInteger; |
在这个示例中,我们创建了一个BigInteger对象,并计算了它的五次方。然后,我们尝试将一个大BigInteger值转换为long类型,当转换结果超出long的范围时,捕获并处理了ArithmeticException异常。
总的来说,BigInteger是一个非常强大的类,它允许Java程序员处理超出标准整数类型范围的数值。不过,需要注意的是,使用BigInteger可能会牺牲一些性能。
