设为首页 加入收藏

TOP

Java泛型使用的简单介绍
2019-08-14 00:08:43 】 浏览:17
Tags:Java 使用 简单 介绍

“泛型”,顾名思义,“泛指的类型”。我们提供了泛指的概念,但具体执行的时候却可以有具体的规则来约束,比如我们用的非常多的ArrayList就是个泛型类,ArrayList作为集合可以存放各种元素,如Integer, String,自定义的各种类型等,但在我们使用的时候通过具体的规则来约束,如我们可以约束集合中只存放Integer类型的元素,如List<Integer> iniData = new ArrayList<>()。


以集合来举例,使用泛型的好处是我们不必因为添加元素类型的不同而定义不同类型的集合,如整型集合类,浮点型集合类,字符串集合类,我们可以定义一个集合来存放整型、浮点型,字符串型数据,而这并不是最重要的,因为我们只要把底层存储设置了Object即可,添加的数据全部都可向上转型为Object。 更重要的是我们可以通过规则按照自己的想法控制存储的数据类型。



我们以ArrayList为例,假如我们要将本月截至今天的日期放到ArrayList中,如果我们不使用泛型,此时我们定义一个ArrayList.


我们向其中加入1号到4号日期


这样有没有问题?大家也看出来了,当然有,虽然都可以表示日期,但却用了Date,LocalDate,我们调用方法直接打印出来,就是这样


我们肯定不想要这样的结果,我们想要的是


如果存储的元素类型只是这两种(假如我们知道),这个时候我们就手动判断一下


这个时候我们就可以达成上述目的了,但大家也知道,这种写法问题问题很大


这时泛型就提供了很好的解决方案,从源头上就制定好规则,只能添加LocalDate类型,那么上述的问题就都得以解决了。


不仅提高了代码的可读性,一眼即可看出我们存储的是LocalDate类型。同时编译器也可很好的利用该信息,编译期间就可进行类型检查,保证了安全性,在get的时候,无需进行强制类型转换。


为使类适应更多的情况,具备更好的扩展性,我们可以将其设置为泛型类,即具有一个或多个类型变量的类,写法如下:


对于泛型标识符,一般有一些约定俗称的写法,如果是表示集合的元素类型,一般用字母E,如我们常用的ArrayList,public class ArrayList<E>,我们自定义如下:


我们还可以用字符K和V表示关键字和值的类型,如我们常用的HashMap,public class HashMap<K,V>,我们也可以自定义如下:


我们还经常用一个字符T表示类型


如何使用泛型类,类型如何实例化,我们只需要保证传入的实参类型和泛型参数类型相同即可。


泛型接口和泛型类的定义基本一致,定义如下:


当我们定义了一个类要实现该接口时,那么该类的泛型类型必须和接口类的泛型类型一致,未传递实参的情况下,继续使用泛型类型T,传递了实参的情况下,泛型类型必须使用实参类型


泛型方法可以定义在普通类和泛型类中,比如泛型类更为常用,一般能用泛型方法解决的问题优先使用泛型方法而不使用泛型类,类型变量放在修饰符的后面,如public static ,public final等的后面。


调用很简单,很一般方法调用是一样的,更方便的是类型不像一般方法做了限定。


另外需要说明的是,定义在泛型类中的泛型方法的泛型变量之间是没有关系的,如这样的代码


类泛型类型为String,方法的泛型类型为Integer,虽然都是用T来表示的。


同时关于泛型方法需要说明的是:


在修饰符public xx与方法名之间非常重要,有< T >这样的才算是泛型方法;仅仅使用了泛型变量并不算是泛型方法。


不论是泛型类还是泛型方法,目前来说其实都是没有做类型限定,无论我们传递什么样类型的变量进去都可以,因为我们在处理逻辑中并没有使用到该类型特有的东西(成员变量、方法等)。假如我们想传递的参数类型仅仅是某个大类(父类)下面的一些小类(子类),那么怎么做呢?


大家也看到了我们在getMax方法中使用了compareTo方法进行比较,但如果我们传入的类型T没有compareTo方法呢,岂不是要报错,因此我们需要做限定,只要限定了是Comparable接口的必然具备compareTo方法,那么改造后就成了这样


同时需要说明的是,此处用的是extends关键字,extends在这里是表示的是绑定了Comparable接口及其子类型,是“绑定、限定”的意思,非“继承”的意思,后面也可以是接口或者类,如果有多个限制,可以使用&分隔,如:


举个例子,定义了一个书籍类和一个小说类


我们再定义一个书柜类用来装书籍以及小说


下面我们就用书柜来装小说


但在jdk7.0后,new Bookcase的时候是可以不用给出泛型类型的,省略的类型可以从变量的类型推断得出,因此如果下面这种写法


此时可以编译通过,我们执行后得出的结果是:


当然我们还可以通过通配符来解决该问题,通配符包括以下几种:


上界通配符、下界通配符、无限定通配符


上界通配符定义方式如下:用extends 关键字,含义是该书柜只能放置小说类书籍(如什么都市小说、爱情小说、玄幻小说都可以),但不能放置父类书籍、其他类如史书、职场类书籍、财经类书籍等,是在使用的时候进行限定,如:


这种定义方式就不会编译错误了。另外关于上界通配符的特点,对上有限制,根据java多态向上造型的原则,不适合频繁插入数据,适合频繁读取数据的场景。


下界通配符定义方式如下:用super关键字,含义就是书柜放置设置了下限,我们只能放置Book书籍以及Novel书籍,却无法再将细分的都市小说、爱情小说类书籍放进去


另外关于下界通配符的特点,和上界通配符正好相反,不适合频繁读取数据,适合频繁插入数据的场景。


无限定通配符意味着可以使用任何对象,因此使用它类似于使用原生类型。但它是有作用的,原生类型可以持有任何类型,而无限定通配符修饰的容器持有的是某种具体的类型。


举个例子:


再说一下< T > 和< ? >之间的区别,初看好像他们都可以表示泛型变量,都可以extends,但它们确实有不同的使用场景


泛型在java中可以说很常用,我们前面提到的集合类,如ArrayList,HashSet,以及Map都使用到了泛型,泛型也是也是我们再进行一些组件封装经常用到的,本文主要介绍了泛型基本概念,使用泛型的好处,泛型类、接口、方法、通配符的简单介绍以及使用方法,最后泛型一般和反射集合使用,通过泛型可以进行类型的灵活传递,通过反射可获取到实体以及类的数据信息,从而实现一些框架、组件的封装,若有不对之处,请批评指正,望共同进步,谢谢!



编程开发网
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇HashMap集合排序方法 下一篇Java枚举类型enum深入理解