java 泛型
java1.5 引入了泛型
没有泛型的年代
// 没有泛型时,如下这样写是不会报错的,现在这样写也不会报错,但是编译器会警告
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Object());
list.add(1);
list.add("foolish");
}那没有泛型时怎么保证类型安全呢,可以如下这样自己封装一个(装饰器)只能加入字符串 的 List,但是我们不能无休止的自己封装仅限某个类的 List。
public class Main {
public static void main(String[] args) {
ListString list = new ListString();
list.add("泛型");
}
static class ListString {
List list = new ArrayList();
public void add(String s) {
list.add(s);
}
public int size() {
return list.size();
}
public String get(int i) {
return (String) list.get(i);
}
}
static class ListInt {
List list = new ArrayList();
public void add(int s) {
list.add(s);
}
public int size() {
return list.size();
}
public int get(int i) {
return (int) list.get(i);
}
}
}有了泛型就简单多了
为什么说 java 泛型是“假泛型”
java 从没有泛型的时代走到有泛型的时代,那 java1.5 之前的代码怎么做兼容? 有两个方案:
擦除【java 的选择】
提供一套全新 API【c#的选择】
什么是擦除,看如下 Main.java 文件
我们对 Main.java 文件使用:
javac -encodeing utf-8 Main.java
进行编译之后,打开编译后的 Main.class 的文件:
对应的字节码文件为:
我们发现 ArrayList<String> stringArrayList = new ArrayList<>();的本质还 是ArrayList var2 = new ArrayList()/NEW java/util/ArrayList,所传递的泛型类被 擦除了。因为 jvm 最终运行的是生成的.class 文件,所以说 java 的泛型是“假泛型”,是 编译期泛型,只在编译期进行泛型类型检查。
擦除带来的问题
你会发现如下代码编译器会发出 Error 警告: 'foo(List)' clashes with 'foo(List)'; both methods have same erasure 这就是擦除带来的问题,两个 foo 方法并不会重载,而是会报 same erasure 错误。
让我们再看一个绕过编译器检查的例子:
泛型的绑定
Last updated
Was this helpful?