安卓基础(泛型)
1. 生活例子:快递盒
想象你有一个快递盒:
- 没有泛型:盒子上没标签,什么都能装(书、水果、手机),但取东西时容易拿错。
- 有泛型:盒子上贴了标签,比如「只能装书」。这样放错东西时立刻被发现,取出时也不用担心类型不对。
2. 代码对比:没有泛型 VS 有泛型
(1) 问题:没有泛型的盒子
class Box {private Object content; // 用 Object 类型,什么都能装public void setContent(Object content) {this.content = content;}public Object getContent() {return content;}
}
使用时的问题:
Box box = new Box();
box.setContent("苹果"); // 放一个字符串
String fruit = (String) box.getContent(); // 必须强制转换,但可能出错!box.setContent(123); // 不小心放了一个整数
String fruit2 = (String) box.getContent(); // 运行时崩溃!ClassCastException
(2) 解决:用泛型的盒子
class Box<T> { // T 是类型标签,比如 String、Integerprivate T content; // 只能装 T 类型的东西public void setContent(T content) {this.content = content;}public T getContent() {return content; // 取出时直接是 T 类型,不用转换}
}
正确使用:
Box<String> fruitBox = new Box<>(); // 标签为 String
fruitBox.setContent("苹果"); // ✅ 只能放字符串
String fruit = fruitBox.getContent(); // ✅ 直接拿到 StringfruitBox.setContent(123); // ❌ 编译直接报错!防止错误
3. 核心概念总结
术语 | 解释 | 生活例子 |
---|---|---|
泛型 | 让一个类/方法可以处理多种数据类型,但保持类型安全 | 贴了标签的快递盒 |
类型参数 | 比如 <T> 中的 T ,表示一个占位符类型(可以是任何字母,如 K 、V ) | 标签上的「书」「水果」等 |
类型安全 | 编译器会检查类型是否正确,防止放入或取出错误类型的数据 | 放错东西立刻被发现 |
强制转换 | 没有泛型时,取出 Object 需要手动转换类型,容易出错 | 拆快递后要猜是什么东西 |
// 定义一个「双格盒子」,可以放两种类型
class DoubleBox<T, U> {private T first;private U second;public DoubleBox(T first, U second) {this.first = first;this.second = second;}public T getFirst() { return first; }public U getSecond() { return second; }
}// 使用:第一个放 String,第二个放 Integer
DoubleBox<String, Integer> box = new DoubleBox<>("年龄", 25);
String key = box.getFirst(); // ✅ 直接是 String
int value = box.getSecond(); // ✅ 直接是 Integer
123
// 一个方法,可以打印任何类型的数组
public <T> void printArray(T[] array) {for (T item : array) {System.out.println(item);}
}// 使用:
String[] names = {"Alice", "Bob"};
printArray(names); // ✅ 自动识别 T 是 StringInteger[] numbers = {1, 2, 3};
printArray(numbers); // ✅ 自动识别 T 是 Integer
生活例子:适配器和视图容器
想象你有一个 快递分拣工厂:
-
RecyclerView.Adapter
就像工厂的流水线机器。 -
FruitHolder
就像专门装水果的快递盒(只能装水果,不能装其他东西)。 -
<FruitAdapter.FruitHolder>
就是告诉流水线机器:“你只能用这种水果快递盒!”
代码逐行解释
1. 类的定义
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.FruitHolder> {
-
RecyclerView.Adapter
:Android 提供的列表管理工具。 -
<FruitAdapter.FruitHolder>
:告诉这个工具:“我只会用FruitHolder
类型的盒子装数据!”
2. 为什么需要 <FruitAdapter.FruitHolder>
?
-
目的:让编译器知道你的
ViewHolder
类型,避免类型转换错误。 -
对比没有泛型的情况:
// 没有泛型时,方法参数是通用的 ViewHolder @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {// 必须强制转换!FruitHolder fruitHolder = (FruitHolder) holder;fruitHolder.textView.setText("苹果"); }
- 风险:如果
holder
不是FruitHolder
,程序会崩溃!
- 风险:如果
-
使用泛型后:
// 使用泛型后,方法参数直接是 FruitHolder @Override public void onBindViewHolder(FruitHolder holder, int position) {// 直接使用,无需转换!holder.textView.setText("苹果"); }
- 安全:编译器保证
holder
一定是FruitHolder
,不会出错。
- 安全:编译器保证