为什么需要泛型类型(Generic types)?

原文地址:http://www.programcreek.com/2012/04/why-do-we-need-generic-types-in-java/

泛型类型在 Java 集合中被广泛使用。 为什么我们需要 Java 中 的泛型类型呢?了解泛型类型可以帮助我们更好地了解很多其他相关的问题。 在本文中,我将使用一个很简单的例子来说明为什么泛型是很有用的。

1. 概述

实现泛型的目的是在编译时发现错误,而不是在运行时。 在编译时查找错误可以节省调试 Java 程序的时间,因为编译时的错误更容易找到和修复。 泛型类型只存在于编译时,这是学习 Java 泛型最重要的事情。

2. 假如没有泛型?

在以下程序中,"Room" 类定义了一个成员对象,我们可以传递任何对象,如 String,Integer 等。

class Room {

    private Object object;

    public void add(Object object) {
        this.object = object;
    }

    public Object get() {
        return object;
    }
}

public class Main {
    public static void main(String[] args) {
        Room room = new Room();
        room.add(60);
        //room.add("60"); //this will cause a run-time error
        Integer i = (Integer)room.get();
        System.out.println(i);
    }
}

当我们添加一个整数并进行转换时,程序运行得很好。 但是如果一个用户意外地添加一个字符串 “60” 进去,编译器不知道这是一个问题,程序运行时会得到 ClassCastException 异常。

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at collection.Main.main(Main.java:21)

您可能会问,为什么不将字段类型声明为 Integer?如果这样,那么 "Room" 类功能就很单一了,因为它只能存储一种类型的东西。

3. 使用泛型

使用泛型修改上面的代码:

class Room<T> {

    private T t;

    public void add(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

public class Main {
    public static void main(String[] args) {
        Room<Integer> room = new Room<Integer>();
        room.add(60);

        Integer i = room.get();
        System.out.println(i);
    }
}

现在如果有人添加 room.add("60"),编译时将提示错误:

以上代码,可以很容易地看到它是如何工作的,另外,也没有必要从 room.get() 转换结果,因为编译知道 get() 将返回一个整数。

4. 总结

使用泛型的原因:

  • 编译时严格的类型检查
  • 消除类型的显示转换
  • 提高代码重用性,如实现通用算法

Java 泛型类型只是一个编译时的概念。在运行期间,所有类型的信息都会被删除,这就是类型擦除。 这是一个有趣的 示例,讲的是如何避免类型擦除中的常见错误,有兴趣的可以看一下。

参考阅读:

results matching ""

    No results matching ""