但在jdk7.0后,new Bookcase的时候是可以不用给出泛型类型的,省略的类型可以从变量的类型推断得出,因此如果下面这种写法
Bookcase<Book> bc = new Bookcase<>(new Novel()); System.out.println(bc.getClass()); bc.get();此时可以编译通过,我们执行后得出的结果是:
class generic.Bookcase class generic.Novel当然我们还可以通过通配符来解决该问题,通配符包括以下几种:
上界通配符、下界通配符、无限定通配符
7.1 上界通配符上界通配符定义方式如下:用extends 关键字,含义是该书柜只能放置小说类书籍(如什么都市小说、爱情小说、玄幻小说都可以),但不能放置父类书籍、其他类如史书、职场类书籍、财经类书籍等,是在使用的时候进行限定,如:
Bookcase<? extends Book> bc = new Bookcase<Novel>(new Novel());这种定义方式就不会编译错误了。另外关于上界通配符的特点,对上有限制,根据java多态向上造型的原则,不适合频繁插入数据,适合频繁读取数据的场景。
7.2 下界通配符下界通配符定义方式如下:用super关键字,含义就是书柜放置设置了下限,我们只能放置Book书籍以及Novel书籍,却无法再将细分的都市小说、爱情小说类书籍放进去
Bookcase<? super Novel> bc = new Bookcase<Novel>(new Novel());另外关于下界通配符的特点,和上界通配符正好相反,不适合频繁读取数据,适合频繁插入数据的场景。
7.3 无限定通配符无限定通配符意味着可以使用任何对象,因此使用它类似于使用原生类型。但它是有作用的,原生类型可以持有任何类型,而无限定通配符修饰的容器持有的是某种具体的类型。
举个例子:
List<?> list = new ArrayList<>(); //无法编译通过 list.add(new Object()); //下面这样的却可以添加任何类型 List<Object> list = new ArrayList<>(); list.add(new Object());再说一下< T > 和< ? >之间的区别,初看好像他们都可以表示泛型变量,都可以extends,但它们确实有不同的使用场景
类型参数< T >声明一个泛型类或泛型方法
无限定通配符< ? >使用泛型类或泛型方法
八. 总结泛型在java中可以说很常用,我们前面提到的集合类,如ArrayList,HashSet,以及Map都使用到了泛型,泛型也是也是我们再进行一些组件封装经常用到的,本文主要介绍了泛型基本概念,使用泛型的好处,泛型类、接口、方法、通配符的简单介绍以及使用方法,最后泛型一般和反射集合使用,通过泛型可以进行类型的灵活传递,通过反射可获取到实体以及类的数据信息,从而实现一些框架、组件的封装,若有不对之处,请批评指正,望共同进步,谢谢!