Java泛型回顾

泛型集合的循环

参考泛型教程

泛型类型检查仅在编译时存在。 在运行时,可以调整代码,以便List具有插入String的其他对象。 不过,这是一个坏主意。

泛型集合利用迭代器进行循环
List<String> list = new ArrayList<String>;

Iterator<String> iterator = list.iterator();

while(iterator.hasNext()){
  String aString = iterator.next();
}

利用新的循环语句,其本质还是利用iterator,只不过是java提供的语法糖
List<String> list = new ArrayList<String>;

for(String aString : list) {
    System.out.println(aString);
}

如果想让自己建的集合可以利用这个语法糖,就要实现以下接口


public class TestCollection {
    public static void main(String[] args) {
        MyCollection<String> stringCollection = new MyCollection<String>();

        for(String string : stringCollection){

        }
    }
}


class MyCollection<E> implements Iterable<E>{

    @Override
    public Iterator<E> iterator() {
        // TODO Auto-generated method stub
        return new MyIterator<E>();
    }

}
//具体循环接口
class MyIterator<T> implements Iterator<T>{

    @Override
    public boolean hasNext() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public T next() {
        // TODO Auto-generated method stub
        return null;
    }

} 

泛型参数class

可以用在方法参数中,对输入参数的class 类型进行限制:

public static <T> T getInstance(Class<T> theClass) throws IllegalAccessException, InstantiationException {

        return theClass.newInstance();
}

String instance = getInstance(String.class);//编译器知道返回类型一定是String

泛型修饰符

一共有三种泛型修饰符

List<?>           listUknown = new ArrayList<A>();
List<? extends A> listUknown = new ArrayList<A>();
List<? super   A> listUknown = new ArrayList<A>();

假设类之间的关系如下:
public class A { }
public class B extends A { }
public class C extends A { }

List<?> listUknown的使用

List<?>意味着我们不知道,集合里面到底是什么类型的变量,可能是List<A>, a List<B>, a List<String> ,既然因为我们不知道确切类型,那么我们**只能将集合中的变量当成Object类型来处理**
//我们可以传入List<A>, a List<B>, List<C>,但是有一个问题,就是我们只能调用Object类的方法,比如下面的systm.out.println
public void processElements(List<?> elements){
   for(Object o : elements){
      System.out.println(o);
   }
}

List<? extends A>

由于知道集合中是A或是A的子类,所以从集合中读出实例,并转化成A类型对象是没有问题的
// List<A>, List<B> or List<C>都可以作为参数传入,但是在循环的过程中,只能调用A的方法,还需要注意一点,就是不能插入元素到该集合,因为你不知道具体元素类型
public  static void  processElements(List<? extends A> elements) {
        for (A a : elements) {
            a.show();
        }
}

List<? super A>

由于我们知道集合中的类型是A或是A的父类,所以插入A或是A的父类是安全的

//在这里我们需要注意一点是,我们A/B/C都是A类型或A类型父类的实例,所以插入安全
public static void insertElements(List<? super A> list){
    list.add(new A());
    list.add(new B());
    list.add(new C());
}

但同样有一个问题,就是读取的时候,由于我们不知道具体集合类型,不能读取(我个人理解就是泛型不知道取出来的类型是什么,也就不能调用相应类型的方法)。除非你将集合中的元素作为Object类型读取

Object object = list.get(0);//正确


A object = list.get(0);//错误

猜你喜欢

转载自blog.csdn.net/whp404/article/details/82634321