深入理解Java包装类与泛型的应用
在 Java 中,包装类(Wrapper Class)和**泛型(Generics)**是两个非常重要的语言特性,它们经常一起使用,特别是在集合框架、类型安全和自动装箱拆箱等场景中。下面从基础概念 → 包装类原理 → 泛型机制 → 二者结合应用 → 常见面试点进行系统讲解。
一、Java 包装类(Wrapper Class)
Java 是强类型语言,基本数据类型(primitive type)不能直接当作对象使用,因此 Java 提供了对应的包装类。
基本类型与包装类对应关系
| 基本类型 | 包装类 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
这些类都位于:
java.lang
示例:
Integernum=Integer.valueOf(10);intx=num.intValue();二、自动装箱与自动拆箱
从 Java 5 开始引入自动装箱(Autoboxing)与自动拆箱(Unboxing)。
自动装箱
Integera=10;等价于:
Integera=Integer.valueOf(10);自动拆箱
Integera=10;intb=a;等价于:
intb=a.intValue();三、包装类的常见方法
以Integer为例:
Integer.parseInt("123");// 字符串转intInteger.valueOf("123");// 字符串转IntegerInteger.toString(10);// 转字符串示例:
intnum=Integer.parseInt("100");四、包装类缓存机制
Integer存在缓存池:
范围:
-128 到 127示例:
Integera=100;Integerb=100;System.out.println(a==b);结果:
true但:
Integera=200;Integerb=200;结果:
false原因:
缓存只覆盖-128 ~ 127。
五、Java 泛型(Generics)
泛型是参数化类型(Parameterized Type)。
目的是:
- 提高类型安全
- 避免类型转换
- 提升代码复用
示例:
List<String>list=newArrayList<>();集合来自:
java.util
六、泛型的基本语法
泛型类
classBox<T>{privateTvalue;publicvoidset(Tvalue){this.value=value;}publicTget(){returnvalue;}}使用:
Box<Integer>box=newBox<>();泛型方法
publicstatic<T>voidprint(Tvalue){System.out.println(value);}调用:
print("Hello");print(123);七、泛型通配符
Java 提供三种通配符:
1 无界通配符
List<?>list表示:
任何类型。
2 上界通配符
List<?extendsNumber>表示:
Number 或其子类。
3 下界通配符
List<?superInteger>表示:
Integer 或其父类。
八、包装类与泛型结合使用
泛型不能使用基本类型,只能使用引用类型。
错误示例:
List<int>list;正确写法:
List<Integer>list;原因:
Java 泛型不支持 primitive type。
九、集合中的包装类应用
例如:
List<Integer>list=newArrayList<>();list.add(10);过程:
10 -> 自动装箱 -> Integer对象取值:
intx=list.get(0);过程:
Integer -> 自动拆箱 -> int十、泛型的类型擦除(Type Erasure)
Java 泛型在编译后会擦除类型信息。
例如:
List<String>List<Integer>编译后:
List这就是:
类型擦除(Type Erasure)
原因:
Java 为了保持向下兼容。
十一、泛型擦除示例
List<String>list=newArrayList<>();编译后等价:
Listlist=newArrayList();并自动添加:
类型检查 强制转换十二、泛型的优点
1 类型安全
编译时检查类型。
2 消除强制转换
Strings=list.get(0);无需:
(String)3 提高代码复用
同一逻辑适用于多种类型。
十三、常见面试问题
1 为什么泛型不能使用基本类型?
因为:
泛型只支持引用类型所以必须使用包装类。
2 Java 泛型什么时候生效?
编译期运行期已经被擦除。
3 List 与 List<?> 的区别?
| 类型 | 含义 |
|---|---|
| List | Object 类型列表 |
| List<?> | 任意类型列表 |
4 Integer 和 int 的区别?
| int | Integer |
|---|---|
| 基本类型 | 对象 |
| 无方法 | 有方法 |
| 不可为null | 可以为null |
十四、实际开发示例
importjava.util.*;publicclassDemo{publicstaticvoidmain(String[]args){List<Integer>numbers=newArrayList<>();numbers.add(10);numbers.add(20);for(Integern:numbers){System.out.println(n);}}}运行过程:
10 -> Integer 20 -> Integer 取出 -> 自动拆箱总结
Java 中包装类与泛型的关系非常紧密:
| 特性 | 作用 |
|---|---|
| 包装类 | 让基本类型变成对象 |
| 泛型 | 提供类型安全 |
| 自动装箱 | 基本类型 → 包装类 |
| 自动拆箱 | 包装类 → 基本类型 |
| 类型擦除 | 泛型只在编译期存在 |
一句话总结:
Java 泛型不能使用基本类型,因此必须借助包装类来实现类型参数化。
如果你愿意,我可以继续给你整理一份Java 面试高频 30 题(包装类 + 泛型 + 集合框架深度版),里面有很多大厂面试非常喜欢问的底层问题。
