欢迎光临
感受代码之美

深入了解Java中的泛型

在Java5后推出了泛型,使我们在编译期间操作集合或类时更加的安全,更方便代码的阅读,而让身为编译性语言的Java提供动态性的反射技术,更是在框架开发中大行其道,从而让Java活起来,下面看一下在使用泛型和反射需要注意和了解的事情。

Java中的泛型是类型可擦除的

Java中的泛型在编译期间是有效的,在运行期间将会被删除,也就是所有泛型参数类型在编译后都会被擦除掉,例如:

public static void test(List<Integer>testParameter) {
}
public static void test(List<String>testParameter) {
}

上面两个方法,除了泛型不同外,其他部分完全相同,但是这两个方法算不算重载呢?答案是不算。因为这段代码在编译之后,泛型类型是会被擦除的,即编译之后这两个泛型都会变成List<E>,所以他们的参数类型是相同的,因此这两个方法不是重载,也不能在同一个类中出现。可以通过getClass()方法,获取他们的类型,以作比较。

不能初始化泛型参数和数据

先看一段代码

class Test<T> {
    //编译不通过
     private T t = new T();
     //编译不通过
     private T[] tArray = new T[5];
     //编译通过
     private List<T> list = new ArrayList<T>();
     }

Java语言是一门强类型,编译型的安全语言,它需要确保运行期间的稳定性和安全性,所以在编译时会对我们所声明的类型进行严格的检查。以上代码在编译期间,编译器会获取T类型,编译后泛型被擦除,所以new T()new T[5]都会出现编译错误。

强制声明泛型的实际类型

在使用泛型时,在大多数情况下应该声明泛型的类型,例如,集合是用来存放User对象的,就应该使用 List<User>来声明,这样可以尽量减少类型的转换,若指使用List而不声明泛型,则集合等同于 List<Object>

泛型不存在继承

先看代码

public static void main(String[] args) {
        // 编译不通过
        List<Object>list = new ArrayList<Integer>();
        // or
        List<Object> list = new ArrayList<Double>();
      }

以上代码的业务逻辑为:有一组元素,不确定元素是整形还是浮点型,但是在确定后创建对应的泛型实现类。但是这种代码的声明方式是错误的,因为泛型之间不存在继承关系,以上逻辑可以换一种实现方式:

public static void main(String[] args) {
        //Number 为Integer 和 Double 的公共父类
        List<Number>numberList = new ArrayList<Number>();
        //使用通配符,代表实际类型是Number类型的子类
        List< ? extends Number> numberList2 = new ArrayList<Integer>();
        //or
        List< ? extends Number> numberList3 = new ArrayList<Double>();
    }

不同场景使用不同的通配符

泛型中支持通配符,可以单独使用?来表示任意类型,也可以使用extends关键字表示传入参数是某一个类或接口的子类;也可以使用super关键字表示接受某一个类型的父类,extends和super的写法一样,extends是限定上界,super为限定下界。

建议使用顺序List<T> List<?> List<Object>

三者都可以容纳所有对象,但是使用时有差别,因为List<T>是确定某一类型,List<?>表示任意类型,List<Object>中全部表示为Object类型,这与不使用泛型无异。List是可读可写的,因为已经明确了,而其他两者在读取时需要进行向下转型,造成了不必要的转型。

使用多重边界限定

如果有业务需求:收钱时需要是公司的员工(继承User),同时亦需要具备收银员的功能(实现Cashier),此时在泛型中可以通过以下代码实现:

public static <T extends User&Cashier>  void CollectMoney(T t){

}

文章整理自:查看出处;

转载请注明来源:四个空格 » 深入了解Java中的泛型

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址