Java 为什么要使用泛型
磊磊

Java 为什么要使用泛型

Java 历史

泛型是从 Java 1.5 出现的。

不用泛型会有哪些不便性

需求:遍历集合

Java 1.5 之前的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TestCase {
@org.junit.Test
@SuppressWarnings(value = {"rawtypes", "unchecked"})
public void test1() {
List list = new ArrayList();
list.add("Sparrow");
list.add(23);
for (Object obj : list) {
// 多态,查找父类的 toString 方法,打印出结果
System.out.println(obj);
}
// 如果我们遍历的时候就想得到自己想要的数据类型
for (Object o : list) {
// 在取 Integer 的时候会报类型转换错误
String obj = (String) o;
System.out.println(obj);
}
}
}

输出:

1
2
3
4
5
Sparrow
23
Sparrow
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at cn.leijiba.config.MyConfig.Test.main(Test.java:20)

图例:

image

问题

如图抛错所示,List 存和取元素都是 Object 类型。所以存在运行时异常,编译不会报错有安全隐患,不方便写代码。

如果我们遍历的时候就想得到自己想要的数据类型有以下解决办法:

解决办法 1

在遍历集合的时候用 instanceof 去判断属于哪个类,再进行强转。

但是这样不合理,类很多,而且只能处理逻辑已知的类型,不知情的类型还是会报错。

解决办法 2

限定存入的类型,也限制取出的类型。所以会有如下代码出现:

但是这样对于未知的类型还是没法判断。而且太过于繁琐。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class StringArrayList {
private List list;

public StringArrayList() {
this.list = new StringList();
}

public String get(int index) {
return (String) list.get(index);
}

public void add(String s) {
list.add(s);
}
}

引入泛型后

1
2
3
4
5
6
7
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
  • 源代码:
    System.out.println(list.get(i));

  • class 字节码:
    System.out.println((String)list.get(i));

可以知道编译器会自动转换。

结论

  1. 减少 Java 5 以往代码的冗余,提高代码复用性

  2. 返回泛型类型时,会自动强转,强转后的变量必须要当前泛型类或者其父类(Object 之类)接收,省时省力

    Java 执行顺序:*.java 文件 (编译) -> *.class 字节码 (运行)-> JVM

  3. 由 2 知:把运行时报错转成了编译就报错,编译没过自然没法运行,减少试错成本

由 Hexo 驱动 & 主题 Keep
访客数 访问量