您的位置:首页 > 其它

集合框架(泛型概述)

2014-02-26 23:12 148 查看
泛型:jdk1.5版本以后出现的一个安全机制。表现格式:< >

好处:

1:将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题。

2:避免了强制转换的麻烦。

只要带有<>的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给<>中传递一个具体的引用数据类型。

 

泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。

为什么? 因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。

在运行时,如何知道获取的元素类型而不用强转呢?

泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,在内部进行一次转换即可,所以使用者不用再做转换动作了。

 

练习:使用泛型按照字符串长度排序字符串,长度相同比较字符串。



[java] view
plaincopy





import java.util.*;  

  

public class TreeSetTest {  

    public static void main(String[] args) {  

        TreeSet<String> s1 = new TreeSet<String>(new StrLenComparator());  

          

        s1.add("aaa");  

        s1.add("asfasf");  

        s1.add("sdds");  

        s1.add("cc");  

        s1.add("tttt");  

          

        Iterator<String> it = s1.iterator();  

          

        while(it.hasNext())  

        {  

            System.out.println(it.next());  

        }  

    }  

  

}  

  

class StrLenComparator implements Comparator<String>  

{  

    public int compare(String o1, String o2) {        

        int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));  

          

        if(num==0)  

            return o1.compareTo(o2);  

        return num;  

    }  

      

}  

什么时候用泛型类呢?

当类中的操作的引用数据类型不确定的时候,以前用的Object来进行扩展的,现在可以用泛型来表示。这样可以避免强转的麻烦,而且将运行问题转移到的编译时期。

[java] view
plaincopy





class Worker  

{  

      

}  

  

class Students  

{  

      

}  

  

//泛型类  

class Utils<QQ>  

{  

    private QQ q;  

    public void setObject(QQ q)  

    {  

        this.q = q;  

    }  

    public QQ getObject()  

    {  

        return q;  

    }  

}  

  

public class GenericDemo {  

    public static void main(String[] args) {  

          

        Utils<Students> u = new Utils<Students>();  

          

        u.setObject(new Students());  

          

        Students w = u.getObject();  

          

    }  

  

}  

集合框架---泛型方法:

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

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



特殊之处:

静态方法不可以访问类上定义的泛型。

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



[java] view
plaincopy





class Demo  

{  

    //泛型方法  

    public <T> void show(T t)  

    {  

        System.out.println("show:"+t);  

    }  

    //泛型方法  

    public <Q> void print(Q q)  

    {  

        System.out.println("print:"+q);  

    }  

}  

public class GenericDemo2 {  

  

    public static void main(String[] args) {  

        Demo d = new Demo();  

          

        d.show("haha");  

        d.print("papa");  

      

    }  

}  

集合框架---泛型接口:



[java] view
plaincopy





//泛型定义在接口上  

interface Inter<T>  

{  

    void show(T t);  

}  

  

class InterImpl <T> implements Inter<T>  

{  

    public void show(T t)  

    {  

        System.out.println("show:"+t);  

    }  

}  

  

public class GenericDemo3 {  

    public static void main(String[] args) {  

        InterImpl<Integer> i = new InterImpl<Integer>();  

        i.show(3);  

    }  

  

}  



泛型中的通配符:可以解决当具体类型不确定的时候,这个通配符就是 ?  ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。

 

泛型限定:

上限:?extends E:可以接收E类型或者E的子类型对象。



[java] view
plaincopy





import java.util.*;  

  

public class GenericDemo4 {  

      

    public static void main(String[] args) {  

//      ArrayList<Person> al = new ArrayList<Person>();  

//      al.add(new Person("aaa"));  

//      al.add(new Person("bbb"));  

//      al.add(new Person("ccc"));  

          

        ArrayList<Student2> al1 = new ArrayList<Student2>();  

        al1.add(new Student2("aaa"));  

        al1.add(new Student2("bbb"));  

        al1.add(new Student2("ccc"));  

          

        printColl(al1);  

          

    }  

      

    public static void printColl(ArrayList<? extends Person2> al)  

    {  

        Iterator<? extends Person2> it = al.iterator();  

          

        while(it.hasNext())  

        {  

            System.out.println(it.next().getName());  

        }  

    }  

      

}  

class Person2  

{  

    private String name;  

    Person2(String name)  

    {  

        this.name = name;  

          

    }  

    public String getName()  

    {  

        return name;  

    }  

      

}  

  

class Student2 extends Person2  

{  

    Student2(String name)  

    {  

        super(name);  

    }  

}  

下限:?super E:可以接收E类型或者E的父类型对象。

 

上限什么时候用:往集合中添加元素时,既可以添加E类型对象,又可以添加E的子类型对象。为什么?因为取的时候,E类型既可以接收E类对象,又可以接收E的子类型对象。

 

下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元素的父类型接收。

 

泛型的细节:

1)、泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是Object类型;

2)、使用带泛型的类创建对象时,等式两边指定的泛型必须一致;

原因:编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了;

3)、等式两边可以在任意一边使用泛型,在另一边不使用(考虑向后兼容);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: