------- android培训、java培训、期待与您交流! ----------
泛型:
jdk1.5以后出现的新特性,用于解决安全问题。
因为集合当中可以添加各种类型数据,如果一开始指定了泛型,后期就不会再存入其他类型的数据。
ArrayList<String> al=new ArrayList<String>();
以上代码定义一个容器,只能存储String类型
容器的迭代器也要申明泛型类型,此类型应与容器声明的泛型类型相同
Iterator<String> it=al.iterator();
泛型的好处总结:
(1)将运行时期出现的类型转换异常,转移到了编译时期,也就是说,存入不同类型时,编译失败。
(2)避免了强转的麻烦。
通常API中有<>的接口或者类时,就可以根据需要定义泛型。(不是必须的)。
泛型类:
当类中要操作的引用数据类型不确定时,
早期定义Object类利用多态性质来完成扩展,
现在定义泛型来完成扩展。
泛型类定义的泛型在整个类中有效,如果被方法使用。
那么泛型类的对象明确要操作的具体类型之后,所有要操作的类型已经固定了。
类上定义的泛型在方法中使用一般做为参数传递就行。
为了让不同的方法可以操作不同的类型,而且类型还不确定。
那么可以将泛型定义在方法上面。定义在方法上的泛型只会作用于这个方法本身。
可以既在类上定义泛型,又在类中的方法上定义不同的泛型。
静态的方法不能使用类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上面。
public static<M>void show(M m)(注意泛型放在返回值修饰符的前面)
泛型可以定义在方法,类,接口以及容器上。
如果实现泛型接口的实现类没有指定泛型的类型就需要再次在类上面指定泛型,在容器上使用泛型时,如果泛型类型不明确,可以用<?>也可以指定为T,但是这样方法上必须指定T,而且在方法中可以对T进行操作。
public static void printcoll(ArrayList<?> al){
Iterator<?> it=al.iterator();
while(it.hasNext());{
system.out.println(it.next());
}
}
public static<T> vodi printcoll(ArrayList<T> al){
Iterator<T> it=al.iterator();
while(it.hasNext());{
T t=it.next();//对T进行了操作
}
容器中定义泛型时:
ArrayList<T> al=new ArrayList<T>();//左右两边要一致都是T。
泛型限定,指定泛型可以接收的范围
<?extends E>接收E类及其子类
<? super E>接收E类及其父类
以下TreeSet构造函数的说明
TreeSet<E>(Comparator<? super E> comparator) 定义比较器时,可以是E类型,还可以是E的父类型,E在创建集合对象时确定 。
public class JiheDemo15 {
public static void main(String[] args) {
ArrayList<A> al=new ArrayList<A>();
al.add(new A("dfg"));
al.add(new A("fghjgj"));
al.add(new B("asd"));
print(al);
ArrayList<B> al1=new ArrayList<B>();
al1.add(new B("dfgg"));
print(al1);
}
public static void print(ArrayList<? extends A> al){//这里的限定意思是可以打印A类
//以及A类的子类型,也就是说,这个参数中有泛型,而且限定在A类或者其子类中。
//这里虽然指定了A类型的集合可以存入A类的子类,但是这里的方法不可以写ArrayList<A>
//只能写ArrayList<? extends A>
Iterator<? extends A> it=al.iterator();
while(it.hasNext()){
A a=it.next();
System.out.println(a.getName());
}
}
}
class A{
private String name;
A(String name){
this.name=name;
}
public String getName(){
return this.name;
}
}
class B extends A{
private String name;
B(String name){
super("abc");
this.name=name;
}
public String getName(){
return this.name;
}
}
/*
*
*TreeSet(Comparator<? super E> comparator)
*TreeSet这个方法的理解,首先如果TreeSet指定了类型,
*那么它所带的比较器可以比较的类型为该指定类型或者是它的父类类型
*也就是说,一个指定了Student类型的TreeSet集合,可以传入一个用于比较父类类型的比较器
*原理就在于父类类型可以指向子类实例对象,也就是传说中的多态。
* class Mycom implements Comparator<Person>{
* public int compare(Person p1,Person p2){//这里person类型就可以接收学生类
*
* }
* }
* TreeSet<Student> ts=new TreeSet<Student>(new Mycom())
* 这里如果比较器定义为Person 那么就可以比较Person的子类Student类还可以比较Worker类
* 这样比较器就不需要写两个了,这就是多态和泛型限定的好处。
*
*/