黑马程序员——java中泛型的简述

来源:互联网 发布:snh48知乎 直弯 编辑:程序博客网 时间:2024/06/06 00:51

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

为什么定义泛型?
定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中取出元素值时,由于是Object的类型,所以取出后要求做强制类型转换,把Object转换为字符串或者Integer类型,在转换过程中,可能会出现转换的类型不符,可能把字符串转为为Integer类型,运行时程序会报错。为了避免强制类型转换以及在类型转换中出错,就引入了泛型,避免了强制类型转换,把出现的错误放在了编译期解决。

泛型
所谓泛型是指将类型参数化,在使用集合时指定集合存放的数据类型,在编译期就能过对存放的类型进行限定,因为指定了存放数据的类型,在取数据时不需要强制类型转换,对于数据与引用数据类型出现的不符也能够在编译期被检测出来,不用等到运行期出现错误。这种参数类型可以用在类、接口和方法的创建中。

泛型的定义:
ArrayList 泛型类型集合
ArrayListT类型变量或说类型参数
ArrayList 中的Integer为类型的实例或实际类型参数

没用泛型:

/**     * 不用泛型的集合     */    public static void main(String[] args) {        // TODO Auto-generated method stub       ArrayList list = new ArrayList();       list.add("abc");       list.add(12);       String str = (String)list.get(0);       Integer i = (Integer)list.get(1);    }}

泛型的应用

/**     *  泛型集合     */    public static void main(String[] args) {        // TODO Auto-generated method stub       ArrayList<String> list = new ArrayList<String>();       list.add("abc");       list.add("OK");       String str1 = list.get(0);       String str2 =  list.get(1);    }}

泛型是提供给javac编译器使用的可以限定集合中的的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去掉“类型”信息,使的程序中的非法输入,使的程序运行效率不受影响,对于参数化的泛型类型,getClass()类型的的返回值和原类型数据完全一样。由于编译生成的字节码会去掉泛型的类型信息,只有跳过编译器,就可以向泛型集合汇中加进其他类型的数据。

泛型练习:

/**     *  判断泛型集合与非泛型集合是否相同     */    public static void main(String[] args) {        // TODO Auto-generated method stub        //有泛型的集合       ArrayList<String> list1 = new ArrayList<String>();       //没有泛型的集合       ArrayList list2 = new ArrayList();       //判断是否是同一字节码       System.out.println(list1.getClass()==list2.getClass());    }

运行的结果是true,字节码相同。

/**     *  利用反射对泛型集合加进其他数据类型     */    public static void main(String[] args) {         //定义泛型       ArrayList<Integer> list = new ArrayList<Integer>();       list.add(15);       try {           //获得add的方法,加进String类型           Class cla = list.getClass();           Method method = cla.getMethod("add", Object.class);           method.invoke(list, "abc");    } catch ( Exception e) {        e.printStackTrace();    }         System.out.println(list.get(1));    }}

运行能够打印出字符串数据,说明字符已经加进去。

泛型不存在继承关系
错:
ArrayList list = new ArrayList();
错:
ArrayList = new ArrayList();
泛型与原始数据兼容:
ArrayList list = new ArrayList();
ArrayList = new ArrayList();
通配符:
只能调用调用不涉及类型参数的的函数
限定通配符的上边界(指定类型的范围):

ArrayList<? Extends Number> x = new`ArrayList<Integer>();

ArrayList<? Extends Number> x = new ArrayList<String>();
限定通配符的下边界:
正确:
ArrayList<?super Integer> x =new ArrayList<Numder>();
错误:
AttayList<?super Integer> x=new ArrayList<Byte>();

练习:

/**     *  泛型练习,HashMap的应用     */    public static void main(String[] args) {        //定义泛型HashMap         Map<String,Integer> map = new HashMap<String, Integer>();         map.put("张三",14);         map.put("李四", 16);         map.put("王五", 18);         //取值          Set<Map.Entry<String,Integer>> set = map.entrySet();          for(Map.Entry<String, Integer> entry:set)          {              System.out.println(entry.getKey()+":"+entry.getValue());          }    }}

泛型方法的定义

/*泛型的方法的定义     * <T>指定T为泛型     * 方法中的所有的T为同一类型数据     */public <T> T  way(T x,T y)    { System.out.println(x+":"+y);        return null;}

练习:

public static void main(String[] args) {        Integer i  = way(12,13);         //当方法中出现不同数据类型时,去类型的共同父类        Number number = way(12.5,12);        Object  abj = way("abc",11);    }    /*泛型的方法的定义     * <T>指定T为泛型     * 方法中的所有的T为同一类型数据     */    static public <T> T  way(T x,T y)    {         System.out.println(x+":"+y);        return null;    }

可以对泛型进行范围的限定:

//限定泛型范围     public <T extends Number> T  way(T x,T y)    {        System.out.println(x+":"+y);        return null;    }
0 0
原创粉丝点击