一.java泛型是Java语言中对类型进行抽象,具体来讲,是把类型参数化的一种语法。
二.简单的泛型如:List<Integer> myIntList = new LinkedList<Integer>();,这样,在往这个容器中增加元素时,编译器会去检查放入容器的类型是否跟容器声明时指定需要的类型一致,否则会报编译时错误。List<T>被称为参数化类型,尖括号中的T是形式类型参数,声明了List<Integer> myIntList = new LinkedList<Integer>();这样的对象之后,在List<T>类中所有的形式类型参数都会被Integer类型代替,使用该类时的入参和所得到的返回类型,也严格受到该类型的限制.但一个泛型类型的声明只被编译一次,并且得到一个class文件,就像普通的class或者interface的声明一样。
推荐的形式类型参数是一个简单的大写字母,比如T,E,K,V等.
三.对泛型类型实例化了两个父子类型的对象后,这两个对象对应的类型并没有父子关系.所以,以下这样的代码:
List<String> ls = new ArrayList<String>(); //1
List<Object> lo = ls; //2
并不合法.
四.如三所说,Collection<Object>,并不表示Collection<T>在T取任意一个类型值时的父类型.那么,我们在方法参数等处用什么来表示所有Collection<T>类型的父类呢?
答案是:Collection<?>.
但是,我的理解:
Collection<?> c = new ArrayList<String>();
c.add(""); // 编译时错误
这样错误的原因是,Collection<?>根本只是提供我们在方法形式参数中使用,用来表示泛型类型实参的可能.
五.List<? extends Shape> shapes.特殊的通配符.如上样式的通配符是对通配符类型的一种限制,表示泛型"泛"得是有限度的,只能表示比Shape小的类型.这里比Shape小的意思是,继承自Shape类,或者Shape类本身的意思.Sink<? super T>,这个限制通配符表示T类型本身,或者它的一个未知父类.
六.使用泛型方法.
static void fromArrayToCollection(Object[] a, Collection<?> c) {
for (Object o : a) {
c.add(o); // 编译期错误
}
}
以上的代码意图是想把任意一个类型的数组放到一个集合类当中,但是会造成编译错误.因为Collection<?> c,并不是一个确定的类型,但是我们确把Object类型放到这个容器中.我们可能想把这个类变成一个泛型类型,在类声明上加上一个<T>,但是,可能在这个类中其他地方,再也不需要用到这个泛型了.我的理解:泛型方法就是考虑了这种情况,我们只要在方法前声明一个<T>,一样可以在方法的形参中使用这个泛型.于是,之前的代码可以写成这样:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
for (T o : a) {
c.add(o);
}
}
这样就是可以满足我们的要求的代码了.
此外
public interface Collection<E> {
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
}
我们也可以使用泛型方法来代替:
public interface Collection<E> {
<T> boolean containsAll(Collection<T> c);
<T extends E> boolean addAll(Collection<T> c);
}
以上也是泛型方法带给我们的好处.
泛型学习简单总结
最新推荐文章于 2022-10-07 11:21:45 发布