JAVA泛型----简单讲解、事例

首先让我们来看一个小例子

public class GenericTest {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("qq");
        list.add("pp");
        list.add(100);

        for (int i = 0; i < list.size(); i++) {
            String name = (String)list.get(i);
            System.out.println("name: "+ name);
        }
    }
看看会报错吗?

会的,输出前两个没问题,但是输出第三个100 时候就报错了...

上面的List集合,既可以添加String类型又可以添加Integer类型,是完全允许的
因为此时的List默认的类型Object类型。
然而在之后的循环中,可能会忘记list里面还有Integer类型的值,很容易出现
java.lang.ClassCastException这种异常,因此,导致此类错误编码过程中不易发现。。

上面的代码有两个问题:
1.当我们将对象放入集合以后,集合不会记住此对象的类型,当再次从集合中取出此对象时,
对象的编译类型就变成了Object类型,运行时候任然为其本身
2.在list.get(i) 取出集合元素的时候,需要人为的强制类型转换到具体的目标类型,
且很容易出现"java.lang.ClassCastException"异常

那么有没有什么办法可以使集合能够记住集合内元素各类型,
且能够达到只要编译时不出现问题,运行时就不会出现“java.lang.ClassCastException”异常呢?
答案就是使用泛型。

什么是泛型?
泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。
那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数。
此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
看着好像有点复杂,首先我们看下上面那个例子采用泛型的写法。


再来看一个小例子..

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("qq");
        list.add("pp");
//        list.add(100);

        for (int i = 0; i < list.size(); i++) {
            String name = (String)list.get(i);
            System.out.println("name: "+ name);
        }
    }

采用泛型写法后,再想往list集合中添加一个Integer类型的对象的时候就会出现编译错误。
通过List<String> 直接限定了list集合中 只能含有String类型的元素,从而在输出的时候无需转换。
因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。

那我们再来看另一个例子..

一个简单的定义泛型的例子
 */
public class GenericTest2 {
    public static void main(String[] args) {
        Box<String> name = new Box<String>("corn");
        System.out.println("name: "+ name.getData());
    }
}

class Box<T> {
    private T data;

    public Box() {

    }

    public Box(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }
}


    /*
    在泛型接口、泛型类和泛型方法的定义过程中,
    我们常见的如T、E、K、V等形式的参数常用于表示泛型形参,
    由于接收来自外部使用时候传入的类型实参。
    那么对于不同传入的类型实参,生成的相应对象实例的类型是不是一样的呢?
     */
    public static void main(String[] args) {
        Box<String> name = new Box<String>("corn");
        Box<Integer> age = new Box<Integer>(71);

        System.out.println("name: "+name.getClass());//com.generic.test.Box
        System.out.println("age: "+age.getClass());  //com.generic.test.Box
        System.out.println(name.getClass() == age.getClass());//true
    }

    /*
        由此,我们发现,在使用泛型类时,虽然传入了不同的泛型实参,
        但并没有真正意义上生成不同的类型,
        传入不同泛型实参的泛型类在内存上只有一个,
        即还是原来的最基本的类型(本实例中为Box),当然,
        在逻辑上我们可以理解成多个不同的泛型类型。
     */



挑取了一些贴出来了,原文在此..

http://www.imooc.com/article/1935







你可能感兴趣的:(泛型)