Java 泛型在设计上为了保证向后兼容和运行时性能,引入了很多“看似反直觉”的限制。下面从常见陷阱 → 原因 → 正确写法三个层面,系统讲讲如何避免泛型坑。
new T() / 创建泛型数组public class Box<T> {
T[] arr = new T[10]; // ❌ 编译错误
}
原因
T 到底是什么✅ 正确做法
@SuppressWarnings("unchecked")
T[] arr = (T[]) new Object[10];
或
List<T> list = new ArrayList<>();
List<int> list = new ArrayList<>(); // ❌
✅ 正确做法
List<Integer> list = new ArrayList<>();
⚠️ 注意:自动装箱有性能成本(高频场景要小心)
class Utils {
static <T> T get(List<T> list) { ... }
}
调用时:
Utils.get(list); // ✅
❌ 错误理解:
Utils<String>.get(list); // ❌ 泛型类语法不对
✅ 泛型方法要写 <T>
instanceofif (obj instanceof List<String>) // ❌
✅ 正确
if (obj instanceof List) { ... }
甚至可以用:
if (obj instanceof List<?>)
void test(List<String> list) {}
void test(List<Integer> list) {} // ❌ 编译错误
原因
擦除后都是 List
✅ 解决
? extends T 不能写List<? extends Number> list = new ArrayList<>();
list.add(1); // ❌
✅ 只能读
Number n = list.get(0);
? super T 不能读具体类型List<? super Integer> list = new ArrayList<>();
list.add(1); // ✅
Integer i = list.get(0); // ❌
✅ 只能当 Object
Object o = list.get(0);
Producer → Extends,Consumer → Super
void copy(List<? extends Number> src,
List<? super Number> dest)
List<String> a = new ArrayList<>();
List<Object> b = a; // ❌
✅ 用通配符
List<? extends Object> b = a;
List list = new ArrayList();
list.add("a");
List<Integer> ints = list; // 警告
int x = ints.get(0); // 运行时 ClassCastException
✅ 避免原始类型
✅ 永远指定泛型类型
✅ 不用原始类型 List
✅ 不试图 new T() / T.class
✅ 方法返回泛型优先用 <T>
✅ 集合 API 参数用 ? extends/super
✅ 警惕擦除导致的运行时错误
如果你愿意,我也可以:
你更想看哪一个?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。