java泛型

Java 泛型

1.首先在没有泛型之前,一旦把一个对象丢进java集合中,集合就会忘记对象的类型,把所有对象当成Object类型来处理。当程序从集合中取出对象时,就需要进行强制类型转换,这种强制类型转换不仅代码臃肿,而且容易引起ClassCastException异常。

复制代码
复制代码
    public class ListErr
    {
        public static void main(String[] args) 
        {
            //创建一个只想保存字符串的List集合
            List strList = new ArrayList();
            strList.add("Struts2权威指南");
            strList.add("基于J2EE的Ajax宝典");
            strList.add("轻量级J2EE企业应用实战");
            //”不小心“把一个Integer对象”丢进"了集合
            strList.add(5);
            for (int i = 0; i < strList.size() ; i++ )
            {
                //因为List里取出的全部是Object,所以必须强制类型转换
                //最后一个元素将出现ClassCastException异常
                String str = (String)strList.get(i);
            }
        }
    }
复制代码
复制代码

2.为了解决这个问题,在1.5前都采用,创建个List对象的方法,但每遇到个集合都要建个对象

复制代码
复制代码
    class StrList
    {
        private List strList = new ArrayList();
        //定义StrList的add方法
        public boolean add(String ele)
        {
            return strList.add(ele);
        }
        //重写get方法,将get方法的返回值类型改为String类型
        public String get(int index)
        {
            return (String)strList.get(index);
        }
        public int size()
        {
            return strList.size();
        }
    }
复制代码
复制代码
复制代码
复制代码
public class CheckType
{
    public static void main(String[] args) 
    {
        //创建一个只想保存字符串的List集合
        StrList strList = new StrList();
        strList.add("Struts2权威指南");
        strList.add("基于J2EE的Ajax宝典");
        strList.add("轻量级J2EE企业应用实战");
        //下面语句不能把Integer对象“丢进”集合中,将引起编译异常
        strList.add(5);
        System.out.println(strList);
        for (int i = 0; i < strList.size() ; i++ )
        {
            //因为StrList里元素的类型就是String类型,所以无需强制类型转换
            String str = strList.get(i);
        }
    }
}
复制代码
复制代码

3.泛型

复制代码
复制代码
有了泛型就方便了,eg

    public class GenericList
    {
        public static void main(String[] args) 
        {
            //创建一个只想保存字符串的List集合
            List<String> strList = new ArrayList<String>();
            strList.add("Struts2权威指南");
            strList.add("基于J2EE的Ajax宝典");
            strList.add("轻量级J2EE企业应用实战");
            //下面代码将引起编译错误
            strList.add(5);
            for (int i = 0; i < strList.size() ; i++ )
            {
                //下面代码无需强制类型转换
                String str = strList.get(i);
            }
        }
    }
复制代码
复制代码

4.当创建带泛型的自定义类时,在定义该类构造器时,构造器名还是和类名一样,不要增加泛型声明。

从泛型类派生子类,接口,父类不能包含类型形参。

下面例子就是错误的。

public class A extends B<T>{},

使用类型通配符“?’”, 它可以匹配任何类型,

public void test(List <?>){}

5.使用时注意:List<String>不是List<Object>子类   ,特殊的泛型(带类型通配符和类型上限),

复制代码
复制代码
    public class Apple<T extends Number>
    {
        T col;
        
        public static void main(String[] args)
        {
            Apple<Integer> ai = new Apple<Integer>();
            Apple<Double> ad = new Apple<Double>();
            //下面代码将引起编译异常
            //因为String类型传给T形参,但String不是Number的子类型。
            Apple<String> as = new Apple<String>();
            
        }
    }
复制代码
复制代码

6.java泛型不支持泛型数组(List<String> aa=new ArrayList<String>[10];),因为java泛型的设计原则是没有unchecked警告就没有ClassCastExcepiton. 我建议大家遇到集合数组等的时候,自己来检验数据的类型

复制代码
复制代码
    public class test {
        public static void main(String[] args) {
            ArrayList[] aa = new ArrayList[10];
            List<Integer> li = new ArrayList<Integer>();
            li.add(3);
            ((Object[]) aa)[1] = li;
            Object target = aa[1].get(0);
            if (target instanceof Integer) {
                Integer s = (Integer) target;
                System.out.println(s);
            }
        }
    }

由于java的泛型只是编译时做下检验,大家不要想的过于强大,他的最大作用只是增强代码的可读性,别的方面也没见多大的作用。
复制代码
复制代码

7.什么时候写泛型?有什么好处?

最简单的体现,只要使用到了带有<>的类和接口,就指定具体对象类型。

 

泛型的好处

1,  将运行时出现的ClassCastException问题,再编译时期给解决了。运行就安全了。

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

 

所以泛型就是JDK1.5后出现的一个安全机制。


泛型的理解?

首先在没有泛型之前,一旦把一个对象丢进java集合中,集合就会忘记对象的类型,把所有对象当成Object类型来处理。

         当程序从集合中取出对象时,就需要进行强制类型转换,这种强制类型转换不仅代码臃肿,而且容易引起ClassCastException异常。

         1,泛型就是传参数。

2,泛型替代了Object。


什么是泛型的擦除和补偿?

泛型是编译时期的安全机制。

         编译时,通过泛型机制,编译器多了多元素类型进行检查的步骤。

         如果检查通过,产生的class文件时不带有泛型的:也就是泛型的擦除。

 

         泛型的补偿:在对元素存储的时候,可以完成类型的判断。

                                     可是在对元素取出的时候,怎么用指定的类型来接收呢?

                                     JVM运行时,会获取元素的类型,并用该类型对元素进行转换即可。


什么时候使用泛型类?

当类中要操作的引用数据类型不确定的时候,以前使用的是共性类型Object,

现在可以使用泛型来解决。


什么时候使用泛型方法?

当方法操作的引用数据类型不确定的时候,就使用泛型方法。

 

如果方法是静态的,是无法访问类上定义的泛型的。

如果该方法还需要泛型。

必须将泛型定义在方法上。


泛型的限定。

如果要对操作的类型进行限定,只操作一部分类型时,可以使用泛型的高级功能。

?extends E:可以接收E类型和E的子类型。这叫泛型的上限。

?super E:可以接收E类型或E的父类型。这叫泛型的下限。


什么时候会用? extends E 呢?(往集合中添加集合的时候经常使用)

一般在存储具体引用类型时,使用这种情况。

因为存储E类型或者E类型的子类型,在取出的时候都可以用E类型来操作这些元素。

这时可以保证类型是安全的。


下限什么时候用?

从集合中取出对象进行操作时,可以使用下限。

例如:比较器。无论集合中的元素对象的类型是什么,只要比较器的指定的类型可以接收这些对象完成比较,就可以了。

所以比较器的类型,可以是集合中当前元素的类型,也可以是该元素类型的父类型。


泛型使用的误区:

1,  凡是安全的都特别严格。一定要保证座左右两边一致。

2, 不能操作特有对象。

参数定义的集合类型是一个范围,而接受的实际参数是以一个实体,该实体肯定会指定该范围中的某一个具体类型。而该类型是创建容器时指定的,到底是哪种类型该方法是不确定的,那么就不可以在该方法内,进行具体类型对象的定义和操作。

 建议定义泛型时,左右两边一定要一致。如果不一致要保证一点,左边在声明时可以声明一个类型范围,右边在实例化时指定的具体类型必须是左边类型范围中的一种。

分类: JavaSE
阅读更多
个人分类: java学习
上一篇学习网站
下一篇ibatis &lt;isGreaterThan&gt;
想对作者说点什么? 我来说一句

Java Generics and Collections

2018年05月09日 2.13MB 下载

关于java泛型的讲解

2011年06月15日 63KB 下载

java泛型机制

2011年11月06日 35KB 下载

JAVA泛型集合

2018年04月26日 3.76MB 下载

全面总结Java泛型

2009年12月17日 81KB 下载

java泛型学习ppt

2011年08月01日 829KB 下载

没有更多推荐了,返回首页

关闭
关闭