泛型集合的循环
泛型类型检查仅在编译时存在。 在运行时,可以调整代码,以便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);//错误