泛型

作者: 比轩 | 来源:发表于2016-10-29 10:26 被阅读74次

    一、泛型技术的由来

    泛型是从JDK 1.5开始出现的一种安全机制。之前的版本会有安全隐患出现,数据类型的问题,导致程序发生类型转换异常。所以,JDK 1.5开发出了泛型技术,解决程序中的安全问题。

    二、泛型如何解决安全问题

    泛型的出现,可以强制集合存储指定的数据类型,其它类型不允许存储。如果指定集合只能存储String,其他类型是存不进来的。

    书写格式:通用格式 集合类<数据类型> 变量 = new 集合类<数据类型>();

    • 强制集合存储指定的数据类型,如果数据类型不符号要求,编译失败
    • 写泛型的时候,前后的类型一致
    • JDK7新特性,泛型前后自动匹配,后面的可以不写 , 空菱形语法

    三、泛型的好处

    • 保证安全:将问题,由运行时期,提前到了编译时期
    • 简化书写,代码量减少
    • 使用泛型,避免了类型的强制转换

    ArrayList<E> 源代码,E就是一个变量而已,在这个类的方法中,写了E,同一个变量。传递什么值,E就就是什么值,有点类似于C/C++的模板一样。

     ArrayList<String>  array =new ArrayList<String>();
    //源代码中的E,就全部变成了,String
    

    迭代器接口 Iterator<E>方法next()返回值也是E,如果迭代器中指定泛型是String类型,Iterator<String>.next()方法返回值,跟着变成了String类型

    以后,如果你需要用一个类,发现类的右边写了一个尖括号<>写泛型了,指定具体的数据类型。当然,存储基本数据类型时,泛型需要写包装类。

    基本数据类型 包装类
    byte Byte
    boolean Boolean
    short Short
    char Character
    int Integer
    long Long
    float Float
    double Double

    四、泛型使用的demo

    /*
     * 集合存储自定义对象,带泛型,迭代器获取
     * Person在之前的demo里面写过
     */
    import java.util.*;
    import cn.itcast.collection.Person;
    public class GenericDemo1 {
        public static void main(String[] args) {
            //ArrayList存储Person
            ArrayList<Person> array = new ArrayList<Person>();
            array.add(new Person("a",10));
            array.add(new Person("b",11));
            array.add(new Person("c",12));
            
            //迭代器迭代集合,集合的泛型怎么写,迭代器跟随集合的泛型
            Iterator<Person> it = array.iterator();
            while(it.hasNext()){
                //it.next()返回值,就是泛型指定的Person,不用强转了
                Person p = it.next();
                System.out.println(p.getName()+"..."+p.getAge());
            }
        }
    }
    

    五、泛型类/方法/接口

    1. 泛型类和方法

    • 泛型类:将泛型,定义在类上,如果类中的任何位置出现了个泛型,和类上的泛型是相同的。工厂类案例 E==定义了一个变量
    • 泛型方法:跟随类的泛型走的。定义泛型不跟着类的走的.在方法的声明上,在返回值类型之前,定义泛型,这个泛型属于方法自己,不属于类上的泛型
    • 静态泛型方法:不可以和类上的泛型相同,如果相同,出现静态不能访问非静态,自定义一个泛型,这个泛型只属于这个静态方法。静态方法的泛型,写在返回值类型前
    import java.util.ArrayList;
    /*
     * 自定义泛型类,和泛型方法
     */
    
    class Generic<QQ>{
        //使用类泛型
        public void show(QQ q){
            System.out.println(q);
        }
      
        //函数自定义泛型<>泛型修饰符在返回类型之前
        public <TT> void function(TT t){
            System.out.println(t);
        }
      
        //内部静态方法,静态不能调用非静态
        public  static <HAHA> void method(HAHA h){
            System.out.println(h);
        }
    }
    public class GenericDemo3 {
        public static  void main(String[] args) {
            Generic<Integer> g = new Generic<Integer>();
            //show方法的参数,跟随泛型走,现在的参数类型是Integer类型
            g.show(100);
            //调用方法function,泛型可以任意传递
            g.function('a');
            
          //静态方法,类名调用,使用方法自定义泛型,不跟随类 ,也不允许跟随类
            Generic.method("随便传");
        }
    }
    

    2. 泛型接口

    接口上定义泛型:

    • 实现类实现接口不指定泛型
    • 实现类实现接口的同时,就实现了泛型

    demo:

    /*
     * 自定义泛型接口,实现类实现接口,不指定泛型
     * 实现类实现接口的同时直接指定泛型
     */
    interface Face<T>{
        public abstract void show(T t);
    }
    
    //定义实现类,实现接口,同时实现泛型
    class FaceImpl2 implements Face<String>{
        public void show(String s ){
            System.out.println(s);
        }
    }
    
    //定义实现类,实现接口,不理会泛型,等待对象指定具体的数据类型
    class FaceImpl<T> implements Face<T>{
        public void show(T t){
            System.out.println(t);
        }
    }
    public class GenericDemo4 {
        public static void main(String[] args) {
            FaceImpl<String> face = new FaceImpl<String>();
            FaceImpl<Integer> face1 = new FaceImpl<Integer>();
            face.show("随便传");
            
            FaceImpl2 face2 = new FaceImpl2();
            face2.show("只能是字符串");
        }
    }
    

    六、泛型的统配和限定

    1. 泛型的通配符

    传统文件系统中,通配符 * 匹配任意的文件名,或者是后缀名 del . del .java 等等。 假设定义方法,做集合的遍历,但是要求的是遍历任意的一个Collection下的子类集合,此时就要使用通配符。泛型中,通配符号?*问号,匹配所有的泛型类型,好处方便遍历集合,弊端在于不能进行强转。

    demo

    /*
     * 泛型的通配符
     */
    import java.util.*;
    
    public class GenericDemo1 {
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("asfd");
            list.add("adsfgsfd");
            list.add("sdfgsd");
            list.add("asertfd");
            list.add("qwey");
            method(list);
        }
        
        /*
         * 定义方法,遍历集合,但是不知道集合的类型
         * 使用  ? 泛型的通配符
         * 缺点:只能遍历。没办法做强转
         */
        public static void method(Collection<?> c){
            Iterator<?> it = c.iterator();
            while(it.hasNext()){
                System.out.println(it.next());
            }
        }
    }
    
    

    2. 泛型的限定

    泛型的限定问题,写泛型的时候,只需要确定子类,或者父类就可以使用泛型的限定,案例员工和经理,实现了限定操作,提高了安全性,避免了数据类型的强制转换

    泛型上限限定 ? extends E 传递E类型 和E的子类

    泛型下限限定 ? super E 传递E类型 和E的父类

    七、增强for循环

    直接给出demo:

    package generic;
    
    import java.util.*;
    
    /*
     * 练习增强for循环
     */
    public class ForeachDemo {
        public static void main(String[] args) {
    
            method2();
        }
    
        /*
         * 普通数据类型的遍历
         */
        public static void method() {
            int[] a = { 6, 8, 8, 9, 10, 674, 687 };
    
            for (int i : a) {
                System.out.print(i + "  ");
            }
    
            System.out.println("");
            char[] b = { 's', 'd', 'f', 'l', 'i' };
    
            for (char i : b) {
                System.out.print(i);
            }
        }
    
        /*
         * 对象数组的遍历
         */
        public static void method1() {
            String[] s = { "saefsadf", "saasdf", "sadfasdfsdf" };
    
            for (String i : s) {
                System.out.println(i.length());
            }
        }
    
        /*
         * 集合的遍历
         */
        public static void method2() {
            Set<String> s = new HashSet<String>();
            s.add("sretgd");
            s.add("dfga");
            s.add("sretwrey5gd");
            s.add("sresdfgrtgd");
            s.add("rt78uj");
            for (String i : s) {
                System.out.println(i.length());
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:泛型

        本文链接:https://www.haomeiwen.com/subject/chfyuttx.html