java-16(2)-泛型

1.泛型

泛型是JDK1.5出现的安全机制。
好处:
1.将运行时期的问题ClassCastException转到了编译时期。
2.避免了强制类型转换。

2.泛型什么时候用呢?

当操作引用的数据类型不确定的时候,就用泛型<>,
将要操作的引用数据类型传入即可。
其实<>就是用于接收具体引用数据类型的参数范围。
在程序找那个,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型。

3.泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全。
4.泛型的擦除&补偿

程序运行时会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。是为了兼容运行的类加载器。
在运行时,通过获取元素的类型进行转换动作,不用使用者在进行强制类型转换了,这个称为泛型的补偿。

5.泛型的演示

public class GenericDemo {
    public static void main(String[] args){
TreeSet<Person> ts = new TreeSet(new ComparatorByAge());
        //在创建集合对象时就明确了要操作的类型,只能传入引用型类。
        //如果没有传入指定的类型编译不通过。
        ts.add(new Person("Wang",20));
        ts.add(new Person("Sun",22));
        ts.add(new Person("Li",23));

   for(Iterator<Person> it = al.iterator(); it.hasNext();){
    //在使用迭代器时也明确了要操作的类型,就避免了下面的强制类型转换。
            Person p =  it.next();
          //Person p = (Person)it.next;
            System.out.println(p.getName()+" "+p.getAge());
        }
    }
}
public class ComparatorByAge implements Comparator<Person> {
//在实现接口的时候明确了操作的指定类型。
    @Override
    public int compare(Person o1, Person o2) {
        int temp = o1.getAge()-o2.getAge();
  return temp==0?o1.getName().compareTo(o2.getName()):temp;
    }
}

6.泛型可以定义在类上,接口上,还有方法上。

/*泛型定义在方法上。
<>位于修饰符之后,返回符之前。
这样可以根据你调用函数时,具体传入的引用数据类型进行操作。
*/
    public<W> void show(W str){
        System.out.println("show:"+str);
    }
//当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。
    public static <Y> void method(Y obj){
        System.out.println("method:"+obj);
    }

//泛型定义在接口上
interface Inter <Y>{//在接口上定义了一个不明确要操作的引用类型
     void show(Y y);
}
class imple2<W> implements Inter<W>{
//在实现接口时没有明确要操作的引用数据类型,而是在创建对象时明确。
    @Override
    public void show(W w) {
        System.out.println("show2:"+w);
    }
}
class imple implements  Inter<String>{
//在实现接口时,明确了要操作的引用数据类型。
    @Override
    public void show(String s) {
        System.out.println("show:"+s);
    }
}

7.自定义泛型类
在JDK1.5之后,使用泛型来接收类中要操作的引用数据类型。
自定义泛型类,当类中操作的引用数据类型不确定时,就用泛型来表示。

public class Tool<QQ>{
    private QQ q;

    public QQ getObject() {
        return q;
    }

    public void setObject(QQ q) {
        this.q = q;
    }
//将泛型定义方法上,当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。
    public<W> void show(W str){
        System.out.println("show:"+str);
    }
    public static <Y> void method(Y obj){
        System.out.println("method:"+obj);
    }
    public void print(QQ str){
        System.out.println("print:"+str);
    }
}
public class Student extends Person {
    public Student() {
    }

    @Override
    public String toString() {
        return "Student:"+getName()+":"+getAge();
    }

    public Student(String name, int age) {
        super(name, age);
    }
    public void show(){
        System.out.println("Student:"+"show");
    }
}

public class GenericDefineDemo3 {
    public static void main(String[] args){
        Tool<Student> tool = new Tool();
        //创建Tool对象时明确了要操作的类型是Student
        tool.setObject(new Student());
        Student stu = tool.getObject();

    }
}

8.泛型的通配符:?未知类型。

可以对类型进行限定。
?extends E :接收E类型或者子类型对象,上限!
?super E: 接收E类型或者E的父类型,下限!
一般存储元素的时候用的都是上限,因为这样取出都是按照上限类型来运算的,不会出现类型安全隐患。
一般对集合中的元素进行取出操作时,用的是下限,比如比较器。
public class GenericAdvanceDemo2 {
    public static void main(String[] args){
        ArrayList<Worker> al = new ArrayList<>();

        al.add(new Worker("Zhang",30));
        al.add(new Worker("Li",20));

        ArrayList<Student> al2 = new ArrayList<>();

        al2.add(new Student("Wang",18));
        al2.add(new Student("Zhao",18));

        ArrayList<Person> al3 = new ArrayList<>();

        al3.add(new Person("Huang",26));
        al3.add(new Person("Dong",26));


        IteratorCollection2(al);
        IteratorCollection2(al2);
        IteratorCollection3(al2);
        IteratorCollection3(al3);



    }
    //迭代并打印集合中的元素。

    public static void IteratorCollection2(Collection<? extends Person> al) {
    //用Collection是因为可以接受任意的集合,提高了代码的复用性,
    //<? extends Person>可以接受Person类型和Person的子类。
        for (Iterator<? extends Person> it = al.iterator(); it.hasNext();){
            Person p = it.next();
            System.out.println(p.getName()+":"+p.getAge());

        }
    }
    public static void IteratorCollection3(Collection<? super Student> al) {
    //<? super Student>可以接受Student类型以及Student的父类
        for (Iterator<? super Student> it = al.iterator(); it.hasNext();){
            System.out.println(it.next());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值