Java 泛型(Generics) 的核心作用是在编译期做类型检查、避免强制类型转换,同时让代码更通用、更安全。下面从 是什么、怎么用、常见场景、注意事项 讲清楚。
泛型:参数化类型
把“类型”当参数传,而不是固定写死。
List list = new ArrayList();
list.add("hello");
Integer i = (Integer) list.get(0); // 运行期可能 ClassCastException
List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0); // 不用强转
class Box<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
使用:
Box<String> box = new Box<>();
box.set("hello");
String s = box.get();
public <T> T getFirst(List<T> list) {
return list.get(0);
}
也可以写成:
public static <T> T getFirst(List<T> list) {
return list.get(0);
}
调用:
String s = getFirst(Arrays.asList("a", "b"));
interface Converter<T, R> {
R convert(T t);
}
实现:
class StringToInt implements Converter<String, Integer> {
public Integer convert(String s) {
return Integer.parseInt(s);
}
}
? 无界通配符List<?> list;
表示:某个未知类型,但不能往里写(除了 null)
List<?> list = new ArrayList<String>();
// list.add("a"); // 编译错误
? extends T(上界通配符)只读,不写
List<? extends Number> list = new ArrayList<Integer>();
Number n = list.get(0);
✅ 适合:生产者(Producer)
? super T(下界通配符)可写,但读出来是 Object
List<? super Integer> list = new ArrayList<Number>();
list.add(1);
✅ 适合:消费者(Consumer)
Producer → Extends,Consumer → Super
// 生产者
void read(List<? extends Number> list) {}
// 消费者
void write(List<? super Integer> list) {}
Map<String, List<Integer>> map = new HashMap<>();
Set<Integer> set = new HashSet<>();
new T()T t = new T(); // 编译错误
✅ 解决方案:
public <T> T create(Class<T> clazz) throws Exception {
return clazz.newInstance();
}
T[] arr = new T[10]; // 错误
✅ 用 Object[] 或 List<T>
class A<T> {
static T t; // 错误
}
List<String> 和 List<Integer>
在运行期都是 List
✅ 当你想让代码 适用于多种类型
✅ 集合、工具类、接口设计
✅ 减少强制类型转换
✅ 提高代码可读性和安全性
泛型 = 编译期类型安全 + 代码复用
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。