Java基础第一阶段——泛型

泛型概述

ArrayList al = new ArrayList();
al.add("abc");
al.add("abc2");
al.add("abc3");
al.add(4);//al.add(new Integer(4)) 自动装箱

Iterator it = al.iterator();
while(it.hasNext()){
    String s = (String) s.next();// 编译ok,运行报错:class cast Exception
    sop(s);
}

问题:如何在编译的时候就可以检查呢?

JDK1.5之后出现的新特性——泛型,用来解决安全问题,是一个安全机制。

定义集合的时候就要明确类型。

ArrayList<String> al = new ArrayList<String>();//定义了一个容器,这个容器要存放的对象类型是String。将运行时出现的问题ClassCastException转移到了编译时期,方便于程序员解决问题,让运行时期问题减少,安全。

Iterator<String> it = al.iterator();// 迭代器也要使用泛型就可以直接取出字符串了。
while(it.hasNext()){
    String s =  s.next();
    sop(s); 
}

泛型使用

泛型格式:通过<>来定义要称作的引用数据类型。

在使用java提供的对象时,什么时候写泛型呢?

通常在集合框架中和常见,只要见到<>就要定义泛型。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>即可。

Comparator

class LenComparator implements Comparator<String>{

    public int compare(String s1,String s2){
        int num =  new Integer(s1.length()).compare(new Integer(s2.length()));//倒叙的话,把是s1和s2位置互换
        if(num==0)
            return s1.compareTo(s2);//倒叙的话,把是s1和s2位置互换
        return num;
    }
}

TreeSet<String> ts = new TreeSet<String>(new LenComparator());

Comparable

泛型类

class Student{}

class Woker{}

class Tool{

    private Object obj;

    public void setObj(object o){
        obj = o;
    }

    public Object getObj(){
        return obj;
    }

}

class Demo{

    public void static main(String[] args){
        Tool t = new Tool();
        t.setObject(new Student());
        Worker w = (Worker)t.getObject();// 早期做法,编译ok,运行报错。
    }

}

修改(泛型类):

class Tool<T>{

    private T obj;

    public void setObj(T o){
        obj = o;
    }

    public T getObj(){
        return obj;
    }

}


Tool<Worker> t = new Tool<Worker>();
t.setObject(new Student());// 编译报错
Worker w = t.getObject(); 

什么时候定义泛型类?

当类中要称作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型类来完成拓展。

泛型方法

泛型也可以定义在方法中,

class Tool<T>{
    public void print(T o){//泛型也可以定义在方法中
        sop(o)
    }

    public void show(T o){
        sop(o)
    }
}

Tool t = new Tool<String>();
t.print("12");
t.show("21");

泛型类定义的泛型,早整个类中有效,如何被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。

class Tool2{
    public void<T> print(T o){//泛型也可以定义在方法中
        sop(o)
    }

    public void<Q> show(Q o){
        sop(o)
    }
}

Tool2 t = new Tool2();
t.show(12);
t.print("12");
t.show("12");

集合就是泛型类。

静态方法泛型

既有泛型方法又有泛型类。

class Tool2<T>{
    public void print(T o){//泛型也可以定义在方法中
        sop(o)
    }

    public void<Q> show(Q o){
        sop(o)
    }
}

Tool2<String> t = new Tool2<String>();
t.print(12);// 编译报错
t.print("12");//ok
t.show("12");//ok
t.show(12);//ok

特殊之处:

class Tool2<T>{
    public void print(T o){//泛型也可以定义在方法中
        sop(o)
    }

    public <Q> void show(Q o){
        sop(o)
    }

    public static void print2(T o){// 无法从上下文
        sop(o)
    }
}

静态方法不可以访问类上定义泛型。如果静态方法存在的应用数据类型不确定,可以定义在方法上,

class Tool2<T>{
    public void print(T o){//泛型也可以定义在方法中
        sop(o)
    }

    public void<Q> show(Q o){
        sop(o)
    }

    public static <W> void print2(W o){// ok
        sop(o)
    }
}

Tool2.print2(123);//ok

位置:放在方法的返回值前面,修饰符后面。

泛型接口

interface Inter<T>{
    show(T t);
}

class InterImpl implements Inter<String>{

    show(String s){
        sop(s);
    }
}

new InterImpl().show("hhh");

code2:

class InterImpl<T> implements Inter<String>{

    show(T s){
        sop(s);
    }
}

new InterImpl<Integer>().show(123);

泛型限定

public static void main(String[] args){

    ArrayList<String> al  = new ArrayList<String>();
    ...
    ArrayList<Integer> al1  = new ArrayList<Integer>();
    ...

    print(al);
    print(al1);
}


public static void print(ArrayList<?> al){

    Iterator<?> it = al.iterator();
    while(it.hasNext()){
        sop(it.next());
    }

}


public static <T> void print(ArrayList<T> al){

    Iterator<T> it = al.iterator();
    while(it.hasNext()){
        // T t = it.next(); 区别就是可以操作
        sop(it.next());
    }

}

?的应用:泛型限定

class Person{

}

class Student extends Person{

}


main(){
    ArrayList<Student> al = new ArrayList<Student>();
    ...
    print(al);
}

public static void print(ArrayList<Person> al){//ArrayList<Person> al = new ArrayList<Student>();//error
    Iterator<Person> it = al.iterator();
}

public static void print(ArrayList<? extends Person> al){//ok
    Iterator<? extends Person> it = al.iterator();
    ...
}

?通配符,可以理解为占位符

泛型的限定
? extends E : 可以接收E类型或者E的子类型。向上限定
? super E: 可以接收E类型或者E的父类型。向下类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值