黑马程序员技术交流社区

标题: 为什么要使用泛型 [打印本页]

作者: shinelyme    时间: 2016-4-20 11:00
标题: 为什么要使用泛型
1- 为什么要用Java泛型?

泛型是自Java 5版本放入一个概念。引入泛型的概念之前,我们看看Java 5.0版本之前的Java代码片断。

在这个例子中,ArrayList是可以在其中添加,删除,修改列表,并获得了列表的所有元素。

package com.yiibai.tutorial.generics;
import java.util.ArrayList;
public > Tom
        Object obj1 = userNames.get(0);
        // Cast to String.
        String userName1 = (String) obj1;
        System.out.println("userName1 = " + userName1);
        // And get the second element
        // (You know it is a String)
        // ==> jerry
        String userName2 = (String) userNames.get(1);
        System.out.println("userName2 = " + userName2);
      
        // Get the 3rd element (Actually it is an Integer).
        // (Error casts happen here).
        String userName3 = (String) userNames.get(2);
        System.out.println("userName3 = " + userName3);
    }
}

在Java 5版本之前的情况:

只包含用于String类型元素的目的创建一个ArrayList对象,但是,添加到这个列表中的元素,程序中并不全是字符串类型(这是完全可能的),当使用这个元素会被转换成String类型,异常将被抛出。

Java 5引入泛型的概念。借助泛型的帮助下,可以创建一个ArrayList对象只允许包含元素使用字符串的类型,而不是允许包含其它类型的元件。

package com.yiibai.tutorial.generics;
import java.util.ArrayList;
public > userNames = new ArrayList

当创建一个ArrayList


2- 通用类,接口2.1- 泛型类

下面的例子定义了一个泛型类。KeyValue 是一个包含对键和值的泛型类。

package com.yiibai.tutorial.generics.ci;
public > {
    private K key;
    private V value;
    public KeyValue(K key, V value) {
        this.key = key;
        this.value = value;
    }
    public K getKey {
        return key;
    }
    public void setKey(K key) {
        this.key = key;
    }
    public V getValue {
        return value;
    }
    public void setValue(V value) {
        this.value = value;
    }
}

K,V在KeyValue

下面是使用 KeyValue 类的例子

package com.yiibai.tutorial.generics.ci;
public > entry = new KeyValue2.2- 继承泛型类

从泛型类扩展一个类可以用于指定泛型参数类型,泛型保留参数或添加泛型参数。

示例1:package com.yiibai.tutorial.generics.ci;
// This >
// And specify K, V
// K = Integer (Phone Number)
// V = String (Name)
public > {
    public PhoneNameEntry(Integer key, String value) {
        super(key, value);
    }
}

使用PhoneNameEntry示例:

package com.yiibai.tutorial.generics.ci;
public >        示例 2:package com.yiibai.tutorial.generics.ci;
// This >
// Specify the parameter K is String.
public > extends KeyValue

使用StringAndValueEntry类的示例:

package com.yiibai.tutorial.generics.ci;
public > entry = new StringAndValueEntry示例3:package com.yiibai.tutorial.generics.ci;
// This >
// It has added a parameter generics I.
public > extends KeyValue2.3- 泛型接口

泛型接口:

package com.yiibai.tutorial.generics.ci;
public interface GenericInterface

例如,这个接口的实现:

package com.yiibai.tutorial.generics.ci;
public > implements GenericInterface2.4- Java不支持通用的Throwable

我们不能创建一个通用类,它是Throwable的子类,因为Java不支持创建这样的类。

编译器的错误信息:

} catch( Mistake3- 通用方法

在类或接口中的方法,可以通用。

package com.yiibai.tutorial.generics.m;
import java.util.ArrayList;
import com.yiibai.tutorial.generics.ci.KeyValue;
public >: To say that this method has two parameters K, V
    // Method returns K.
    public static

例如,使用泛型方法:

package com.yiibai.tutorial.generics.m;
import java.util.ArrayList;
import com.yiibai.tutorial.generics.ci.KeyValue;
public > entry1 = new KeyValue4- 通用对象初始化

有时候,要初始化一个通用对象:

// Generic Object Initialization
T t = new T; // Error

如果想初始化通用对象,需要传递 Class

package com.yiibai.tutorial.generics.o;
import java.util.Date;
public >        package com.yiibai.tutorial.generics.o;
public > {
    private T tobject;
    public MyGeneric(Classpackage com.yiibai.tutorial.generics.o;
public > mg = new MyGeneric5- 泛型数组

可以声明泛型数组,但不能初始化通用数组。

// You can declare a generic array of generic.
T myarray;
// But you can not initialize a generic array.
// (This is not allowed).
T myarray = new T[5];  // Error!

应用示例:

package com.yiibai.tutorial.generics.a;
public > {
    private T array;
    // Contructor.
    public GenericArray(T[] array) {
        this.array = array;
    }
    public T getArray {
        return array;
    }
    // Returns the last element of the array.
    public T getLastElement {
        if (this.array == null || this.array.length == 0) {
return null;
        }
        return this.array[this.array.length - 1];
    }
}package com.yiibai.tutorial.generics.a;
public > gArray = new GenericArray

回到为什么Java不支持初始化数组通用的问题:

// Why Java don't support to initialize Generic array?
T genericArray = new T[10]; // Error!// Suppose that Java allows to initialize  Generic array:
T  tarray = new T[10];
// At the time of compilation, the compiler will consider T as Object.
// This command is equivalent to.
T tarray  = new Object[10];
// At runtime of the application, if T is defined as String.
// It means that:
String tarray = new Object[10];
// The above is not allowed. Reason:
// Type mismatch: cannot convert from Object to String

如果想初始化泛型数组,需要传递类

package com.yiibai.tutorial.generics.a;
import java.lang.reflect.Array;
public > {
   private Classpackage com.yiibai.tutorial.generics.a;
public > garray = new GArray6- 使用泛型通配符

在通用代码,问号(?),称为通配符,代表一个未知的类型。 通配符参数化类型是一个泛型类型,其中至少一种类型的参数是一个通配符的一个实例。 通配符参数化类型的实例是Collection>, List extends Number>, Comparator super String> 和 Pair

在不同地方的通配符有不同的意义。 例如

Collection> coll = new ArrayList

一些无效的声明。

// String is not sub> list = new ArrayList6.1- 带通配符的例子package com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
public > listString = new ArrayListpackage com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
import java.util.List;
public > list) {
        for (Object e : list) {
System.out.println(e);
        }
    }
    public static void main(String[] args) {
        List

package com.yiibai.tutorial.generics.w;
import java.util.ArrayList;
public >   
        // A list containing the elements of type String.
        ArrayList6.3- 通配符不能加入new操作符

通配符参数化类型不会出现在新的表达具体类型。它只是通过Java泛型已使用的任何特定方案有效实施的规则。

// 通配符不能参加new运算符 List extends Object> list= new ArrayList extends Object>;






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2