复习泛型的一些知识

来源:互联网 发布:中国铁建房地产知乎 编辑:程序博客网 时间:2024/05/04 15:07
  • 初识泛型
  • 了解泛型
  • 泛型类
  • 泛型方法
  • 泛型接口(不常用)
  • 泛型限定

初识泛型

  1. 泛型是JDK1.5引入的新特性,用于解决类型安全问题
  2. 好处:编译时提前发现可能存在的类型转换异常;避免强制转换的麻烦
  3. 所谓泛型,就是变量类型的参数化
  4. API文档中,有<>尖括号的地方,就可以使用泛型
import java.util.TreeSet;public class Test {    public static void main(String[] args) {        TreeSet<String> ts = new TreeSet<String>();        ts.add("1");        ts.add("2");        ts.add("3");        System.out.println(ts);    }}

了解泛型

ArrayList< E > 类定义和ArrayList< Integer > 类引用中涉及的术语
1. 整个称为ArrayList< E >泛型类型
2. ArrayList< E > 中的E称为类型变量或类型参数
3. 整个ArrayList< Integer > 称为参数化的类型
4. ArrayList< Integer > 中的Integer 称为类型参数的实例实际类型参数
5. ArrayList< Integer > 中的<> 念着typeof
6. ArrayList 称为原始类型
7. 参数化类型不考虑类型参数的继承;创建数组实例时,数组的元素不能使用参数化的类型

Vector<String> v = new Vector<Object>(); //错误Vector<Object> v = new Vector<String>(); //也错误Vector<Integer> vectorList[] = new Vector<Integer>[10];//错误

泛型类

当类中操作的引用数据类型不确定时,我们可以自定义泛型类。

class Tools<T>{}
public class Test {    public static void main(String[] args) {        new Tools<String>().sop("test.");    }}class Tools<T> {    public void sop(T t) {        System.out.println(t);    }}

  看上面的程序,在定义Tools类时,不知道要操作的是什么类型,因此将Tools定义为泛型类,到使用时确定操作对象为String类型,就将类型参数指定为String了。


泛型方法

  泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。

public <T> void show(T t) // 注意:<>放在修饰符后面,返回值前面{}
public class Test {    public static void main(String[] args) {        Tool_A<String> a = new Tool_A<String>();        a.sop("a");        a.sop(1); //编译时报错        a.show(1.2222);        Tool_B b = new Tool_B();        b.show("a");        b.show(1);    }}class Tool_A<T> {    // 该类A是泛型类,这个sop方法根据类型参数,确定运行时操作的类型    public void sop(T t) {        System.out.println("Tool_A sop:  " + t);    }    // 泛型类和泛型方法可以同时定义,且不冲突。这个show方法是泛型方法,,可以接收不同的类型    public <T> void show(T t) {        System.out.println("Tool_A show:  " + t);    }}class Tool_B {    // 如果既不是泛型类,又不是泛型方法,方法参数的类型必须确定    public void show(String t) {        System.out.println("Tool_B show:  " + t);    }    // 该类B不是泛型类,这个show方法是泛型方法,可以接收不同的类型    public <T> void show(T t) {        System.out.println("Tool_B show:  " + t);    }}

特殊情况

class Tool_A<T> {    public static void method(T t) { //错,静态方法不可以访问定义类上的泛型    }    public static <T> void method(T t) {//对,如果静态方法操作的引用数据类型不确定,可将泛型定义在方法上    }}

泛型接口

class Aclass implements A<String>{    @Override    public void sop(String t) {        // TODO Auto-generated method stub    }}interface A<T>{    public abstract void sop(T t);} 

  泛型还能定义在接口上,如果定义泛型接口后还是不知道什么类型,可以将实现类继续定义为泛型类,由实现类确定具体类型。


泛型限定

  1. < ? >代表通配符,用于接收不确定的类型
  2. < ? extends E > : 可以接收E类型或者E的子类型。
  3. < ? super E >: 可以接收E类型或者E的父类型。
import java.util.*;public class Test {    public static void main(String[] args) {        ArrayList<String> al1 = new ArrayList<String>();        al1.add("AL1");        al1.add("AL2");        al1.add("AL3");        ArrayList<Integer> al2 = new ArrayList<Integer>();        al2.add(1);        al2.add(2);        al2.add(3);        printCollection(al1);        printCollection(al2);    }    public static void printCollection(ArrayList<?> al) {         Iterator<?> it = al.iterator();        while (it.hasNext()) {            System.out.println(it.next());        }    }}

  这个程序,如果printCollection(ArrayList< ? > al)改为printCollection(ArrayList< T > al)会出错,因为上面< T >这种形式是在声明泛型的类或方法的时候限制了可以用的泛型类型;而< ? >形式是在使用的时候限制了引用的类型。

//对上面的程序来说,以下情况两句printCollection都错printCollection(ArrayList<T> al) {    ×//对上面的程序来说,以下情况printCollection(al1);错printCollection(ArrayList<Integer> al) {    ×
import java.util.*;public class Test {    public static void main(String[] args) {        //TreeSet(Comparator<? super E> comparator)         TreeSet<Student> ts = new TreeSet<Student>(new PersonComparator());        ts.add(new Student(12));        ts.add(new Student(14));        ts.add(new Student(13));        System.out.println(ts);//[12, 13, 14]    }}class Person {    public int age;}class Student extends Person {    public Student(int age) {        this.age = age;    }    @Override    public String toString() {        return Integer.toString(this.age);    }}class PersonComparator implements Comparator<Person> {    @Override    public int compare(Person p1, Person p2) {        return new Integer(p1.age).compareTo(new Integer(p2.age));    }}

  上面的程序,由于TreeSet指定的比较器使用了泛型限定TreeSet(Comparator< ? super E > comparator) ,因此就算再写一个Person的子类Worker,也可以直接继续用这个比较器,很方便。

0 0
原创粉丝点击