Java泛型集合与泛型类

泛型的本质是什么

什么是泛型,泛型是一种模板技术,就好比排序,所有的排序策略,核心问题是比较和交换,如果一种算法对double有效,则只要提供比较大小的规则,该算法也对String甚至任意数据类型有效,而泛型可以使得这样的排序算法一个实现就应用到多中情形。

结合这种概念,就有了泛型集合,好比ArrayList集合的实现,无论对于什么数据类型,其算法结构都是一样的,于是从JDK5后有了泛型集合。

泛型有什么好处

当然,有了泛型集合和泛型技术后,泛型带来的好处就不只是代码重用了,还包括类型安全,以及更好的可读性。要知道下面的代码,在编写代码的时候是不会报错的,要命的是在运行的时候就会:

1 List list1 = new ArrayList();// 非泛型集合
2 list1.add("testString");
3 list1.add(Integer.valueOf(10));
4 for (Object s : list1) {
5     Integer num = (Integer) s;
6     // 类型不安全,会抛出异常
7 }

但是如果是泛型集合,你在编写代码的时候JDK就直接告诉你这里不可以这么使用了:

List list2 = new ArrayList();
//list2.add(1);//类型检查,不是允许的类型无法放入集合

这就是所谓的类型安全了。这是泛型的第二个好处。

当然泛型的另外一个好处就是增强可读性,取出数据的时候不再有完全没有意义的强制类型转换,因为程序员应该知道这个类型是什么。

 

泛型的非协变性

Java中的泛型集合不是协变的,下面的代码你觉得可以编译通过吗:

List list3 = new ArrayList();
List list4 = list3; 
    
   

看起来没什么问题对吧,一个是Object集合,一个是String集合,完全兼容啊,事实上是不行的,如果行的话,泛型集合ArrayList的实例就可以装入任何对象了不是吗?

这里还有个小知识:Java的泛型支持是编译期技术,所谓的类型擦除就是这个意思,我们后面再详细聊。

那么这个问题怎么解决呢?需求是肯定存在的呀,比如我们有个方法定义:

public static void printElements(List objs) 
    
   

这个方法希望接受任何List集合,显然通过上面的内容,我们知道传参数是传不进去的。

解决的办法很简单,讲List 换成List,这个问号就是泛型语法中的任何类型的意思,上面的代码换成这样的语法,就可以接受任何类型了:

//方法声明
public static void printElements(List objs) 
//方法调用
List list5 = new ArrayList();
printElements(list5);

 

当然,?是没有任何约束,我们也可以对接受的类型进一步约束,比如下面的方法定义:

public static void printElements(List<? extends Parent> objs)

 

这样我们的方法要求集合的元素必须是Parent类的子类,比如Number可以限制为数字,别问我怎么知道Number的 (#^.^#)

当然,很多同学还见过这种的:

public static void printElements(List<? super Parent> objs)

反之,这样限制了参数必须是List集合且集合的元素必须是Parent类的父类。(这是super在Java中的第三种用法,你知道还有哪两种吗?)

 

下次我给大家分享泛型类,静态泛型方法,有兴趣的关注我的博客喲。

转载于:https://www.cnblogs.com/octopusedu/p/10852881.html

你可能感兴趣的:(Java泛型集合与泛型类)