一、泛型
1、泛型:jdk1.5版本,出现的技术。是一个安全机制。表现格式:< >
2、泛型技术的由来:
集合中可以存储任意类型对象,但是在取出时,如果要使用具体对象的特有方法时,需要进行向下转型,如果存储的
对象类型不一致,在转型过程中就会出现ClassCastException异常。
这样就给程序带来了不安全性。在jdk1.5以后就有了解决方案。就是泛型技术。解决方案就是,在存储元素时,就不
允许存储不同类型的元素。存储了就编译失败。所以就需要在存储元素时,在容器上明确具体的元素类型。这其实和
数组定义很像。
3、好处:
1)将运行时期的ClassCastException异常转移到了编译事情,进行检查,并以编译失败来体现。这样有利于程序员尽早
解决问题。
2)避免了向下转型(强转)的麻烦
4、什么时候用泛型类呢?
1)当类中的操作的引用数据类型不确定的时候,以前用的Object来进行扩展的,现在可以用泛型来表示。这样可以避
免强转的麻烦,而且将运行问题转移到的编译时期。
2)只要在使用类或者接口时,该类或者接口在api文当描述时都带着<>就需要在使用时,定义泛型。
3)其实,泛型无非就是通过<>定义了一个形式参数。专门用于接收具体的引用类型。
在使用时,一定要传递对应的实际参数类型。
5、泛型的擦除:
泛型技术是用于编译时期的技术,编译器会按照<>中的指定类型对元素进行检查,检查不匹配,就编译失败,匹配,
就编译通过,通过后,生成的class文件中是没有泛型的。这就成为泛型的擦除。
6、泛型的补偿:
运行时,可以根据具体的元素对象获取其具体的类型。并用该类型对元素进行自动转换。
7、泛型的应用:
//泛型类:将泛型定义在类上。
class Tool<Q> {
private Q obj;
public void setObject(Q obj) {
this.obj = obj;
}
public Q getObject() {
return obj;
}
}
//当方法操作的引用数据类型不确定的时候,可以将泛型定义在方法上。
public <W> void method(W w) {
System.out.println("method:"+w);
}
//静态方法上的泛型:静态方法无法访问类上定义的泛型。如果静态方法操作的引用数据类型不确定的时候,必须要
将泛型定义在方法上。
public static <Q> void function(Q t) {
System.out.println("function:"+t);
}
//泛型接口.
interface Inter<T> {
void show(T t);
}
class InterImpl<R> implements Inter<R> {
public void show(R r) {
System.out.println("show:"+r);
}
}
7、泛型的通配符:?
当操作的不同容器中的类型都不确定的时候,而且使用的都是元素从Object类中继承的方法。这时泛型就用通配符?
来表示即可。
8、泛型限定:
1)上限:?extends E:可以接收E类型或者E的子类型对象。
2)下限:?super E:可以接收E类型或者E的父类型对象。
3)上限什么时候用:往集合中添加元素时,既可以添加E类型对象,又可以添加E的子类型对象。为什么?因为取的
时候,E类型既可以接收E类对象,又可以接收E的子类型对象。
4)下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元素的父类
型接收。
9、演示上限或者下限的应用体现。
有一个容器就可以体现上限又可以体现下限。该容器就是TreeSet。
它的构造函数都有体现。
TreeSet(Collection<? extends E> c) 上限
TreeSet(Comparator<? super E> comparator)下限
class TreeSet<E>{
public TreeSet(){}//构造一个空的TreeSet集合。
public TreeSet(Collection<? extends E> coll){}//构造时将指定的Collection中的元素存储到TreeSet集合。
public TreeSet(Comparator<E> comparptor){}//TreeSet构造时就明确比较器。要比较谁根据集合中的元素类型而定。
public boolean add(E e){}
二、foreach循环语句
1、jdk1.5以后 出现的新方式。这种升级就是简化书写。 Collection有了一个父接口,Iterable该接口封装了iterator方
法,同时提供了一个新的语句。foreach语句。
2、格式:
for(变量类型 变量名 : Collection集合or数组)
{
}
1)//用foreach遍历集合
for(String s : al){
System.out.println(s);
}
2)//用foreach遍历数组
int[] arr = {7,23,1,67,90,8};
for(int i : arr){//只为遍历元素,无法操作角标。
System.out.println("i="+i);
}
3、在使用增强for循环时,不能对元素进行赋值
4、和传统for循环有什么区别呢?
1)foreach循环特点:必须明确被遍历的目标。没有目标没用。目的只能是数组或者Collection集合。
2)如果要对数组的中的元素进行特定操作时,建议传统for循环,通过角标完成。