泛型的意义及使用

来源:互联网 发布:有没有唱歌软件 编辑:程序博客网 时间:2024/06/07 19:14

微笑微笑微笑泛型处理有什么作用,java泛型思想,泛型深入浅出使用。本文为初学时收集到的好例子,希望给初学的你一点帮助。

引言

第一段代码

 

importjava.util.ArrayList;

importjava.util.List;

publicclass fanxingmain {

    publicstaticvoid main(String[] args) {

        //TODO Auto-generated method stub

       

        Listlist = new ArrayList();

       list.add("qqyumidi");

       list.add("corn");

       list.add(100);

 

       for(int i = 0; i <list.size(); i++) {

           String name = (String) list.get(i);// 1

           System.out.println("name:" + name);

       }

 

 

    }

 

}

执行结果如下

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
 at we.main(we.java:18)

定义了一个List类型的集合-动态数组,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型

第一段主要存在两个问题:

1.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

2.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。

 

第二段代码

public class fanxingmain {

    publicstatic void main(String[] args) {

       //TODO Auto-generated method stub

      

         List<String> list = newArrayList<String>();

            list.add("qqyumidi");

            list.add("corn");

            list.add(100);   //1

 

            for (int i = 0; i < list.size();i++) {

                String name = list.get(i); // 2

                System.out.println("name:"+ name);

            }

 

 

    }

 

}}

 

执行结果如下:

Exception in thread "main"java.lang.Error: Unresolved compilation problem:

    Themethod add(int, String) in the type List<String> is not applicable forthe arguments (int)

 

    atfanxingmain.main(fanxingmain.java:16)

采用泛型写法后,在//1处想加入一个Integer类型的对象时会出现编译错误,通过List<String>,直接限定了list集合中只能含有String类型的元素,

从而在//2处无须进行强制类型转换,因为此时,集合能够记住元素的类型信息,编译器已经能够确认它是String类型了。

 

  注意:没有泛型数组一说…..

JAVA泛型思想

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。Java语言引入泛型的好处是安全简单。

在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

 

 

使用泛型与不使用泛型比对

使用泛型例子

 

classGen<T> {

    private T ob; // 定义泛型成员变量

 

    public Gen(T ob) {

        this.ob = ob;

    }

 

    public T getOb() {

        return ob;

    }

 

    public void setOb(T ob) {

        this.ob = ob;

    }

 

    public void showType() {

        System.out.println("T的实际类型是: " + ob.getClass().getName());

    }

}

 

publicclass GenDemo {

    public static void main(String[] args) {

        // 定义泛型类Gen的一个Integer版本

        Gen<Integer> intOb = newGen<Integer>(88);

        intOb.showType();

        int i = intOb.getOb();

        System.out.println("value= "+ i);

       System.out.println("----------------------------------");

        // 定义泛型类Gen的一个String版本

        Gen<String> strOb = newGen<String>("Hello Gen!");

        strOb.showType();

        String s = strOb.getOb();

        System.out.println("value= "+ s);

    }

}

 

没有使用泛型

 

class Gen2 {

   private Object ob; // 定义一个通用类型成员

 

   public Gen2(Object ob) {

        this.ob = ob;

    }

 

   public Object getOb() {

       return ob;

    }

 

   public void setOb(Object ob) {

       this.ob = ob;

    }

 

   public void showTyep() {

       System.out.println("T的实际类型是: " + ob.getClass().getName());

    }

}

 

public class GenDemo2 {

   public static void main(String[] args) {

       // 定义类Gen2的一个Integer版本

       Gen2 intOb = new Gen2(new Integer(88));

       intOb.showTyep();

       int i = (Integer) intOb.getOb();

       System.out.println("value= " + i);

       System.out.println("---------------------------------");

       // 定义类Gen2的一个String版本

       Gen2 strOb = new Gen2("Hello Gen!");

       strOb.showTyep();

       String s = (String) strOb.getOb();

       System.out.println("value= " + s);

 

 

 

泛型在重构中的应用

原始代码

public class StringFoo {

    private String x;

 

    public StringFoo(String x) {

        this.x = x;

    }

 

    public String getX() {

        return x;

    }

 

    public void setX(String x) {

        this.x = x;

    }

}

 

public class DoubleFoo {

    private Double x;

 

    public DoubleFoo(Double x) {

        this.x = x;

    }

 

    public Double getX() {

        return x;

    }

 

    public void setX(Double x) {

        this.x = x;

    }

}

 

 

  

 

Java 5之前重构

4

5

6

7

8

9

10

11

12

13

14

15

public class ObjectFoo {

    private Object x;

    public ObjectFoo(Object x) {

        this.x = x;

    }

    public Object getX() {

        return x;

    }

    public void setX(Object x) {

        this.x = x;

    }

}

 

1

2

3

4

5

6

7

8

9

10

public class ObjectFooDemo {

    public static void main(String args[]) {

        ObjectFoo strFoo = new ObjectFoo(new String("Hello Generics!"));

        ObjectFoo douFoo = new ObjectFoo(new Double(new Double("33")));

        ObjectFoo objFoo = new ObjectFoo(new Object());

        System.out.println("strFoo.getX=" + (String) strFoo.getX());

        System.out.println("douFoo.getX=" + (Double) douFoo.getX());

        System.out.println("objFoo.getX=" + objFoo.getX());

    }

 

Java 5之后泛型重构

11

12

13

14

15

16

17

18

19

20

21

22

class GenericsFoo<T> {

    private T x;

    public GenericsFoo(T x) {

        this.x = x;

    }

    public T getX() {

        return x;

    }

    public void setX(T x) {

        this.x = x;

    }

}

public class GenericsFooDemo {

    public static void main(String args[]) {

        GenericsFoo<String> strFoo = new GenericsFoo<String>("Hello Generics!");

        GenericsFoo<Double> douFoo = new GenericsFoo<Double>(new Double("33"));

        GenericsFoo<Object> objFoo = new GenericsFoo<Object>(new Object());

        System.out.println("strFoo.getX=" + strFoo.getX());

        System.out.println("douFoo.getX=" + douFoo.getX());

        System.out.println("objFoo.getX=" + objFoo.getX());

    }

}

 

java泛型通配符泛型

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public class CollectionGenFooDemo {

     

    public static void main(String args[]) {

         

        //CollectionGenFoo<ArrayList> listFoo = null;

         

        //listFoo = new CollectionGenFoo<ArrayList>(new ArrayList());

    

 

   CollectionGenFoo<?> listFoo1 = null;

         

        listFoo1=new CollectionGenFoo<ArrayList>(new ArrayList());

         

        System.out.println("实例化成功!");

     

    }

 

}

注意:

1、如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类。

2通配符泛型不单可以向上限制,如<? extends Collection>,还可以向下限制,如<?super Double>,表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。

3泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似。