Java泛型

1、概述

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,所操作的数据类型被指定为一个参数。

假定有这样一个需求:写一个排序方法,能够对整形数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?这里就可以使用到 Java 泛型。我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。

2、泛型方法

泛型方法在调用时接收任意类型的参数。根据传递给泛型方法的参数类型,编译器(Compiler)适当地处理每一个方法调用。

①规范

  • 形如:public <E> void doSomething(E e)

  • 泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回值类型之前。

  • 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。形如:
    public <E, F> void handle(E e, F f)

  • 类型参数能被用来声明返回值类型

  • 泛型方法体声明的类型参数只能代表引用型类型,不能是原始类型(int、double、char等)。

  • 泛型可定义有界类型参数。形如:public <E extends Comparable<T>> void handle(E e)

②实例

不带返回值

import java.util.ArrayList;

/**
 * @author Hanlin Wang
 */

public class GenericType {
    public static void main(String[] args) {
        GenericType genericType = new GenericType();
        genericType.showClass(new ArrayList<String>());
        genericType.showClass(new String());
        genericType.showClass(new Integer(1));
    }

    public <E> void showClass(E e){
        System.out.println(e.getClass());
    }
}

运行结果:

class java.util.ArrayList
class java.lang.String
class java.lang.Integer

带返回值

import java.util.ArrayList;

/**
 * @author Hanlin Wang
 */

public class GenericType {
    public static void main(String[] args) {
        GenericType genericType = new GenericType();
        System.out.println(genericType.showClass(new ArrayList<String>()));
        System.out.println(genericType.showClass(new String("haha")));
        System.out.println(genericType.showClass(new Integer(1)));
    }

    public <E> E showClass(E e){
        return e;
    }
}

运行结果:

[]
haha
1

多个泛型参数

import java.util.ArrayList;

/**
 * @author Hanlin Wang
 */

public class GenericType {
    public static void main(String[] args) {
        GenericType genericType = new GenericType();
        genericType.showClass(new Object(), new String());
    }

    public <E, F> void showClass(E e, F f){
        System.out.println(e.getClass());
        System.out.println(f.getClass());
    }
}

运行结果:

class java.lang.Object
class java.lang.String

指定泛型界限

/**
 * @author Hanlin Wang
 */

public class GenericType {
    public static void main(String[] args) {
        GenericType genericType = new GenericType();

        genericType.show(new String());
    }

    public <E extends Comparable<E>> void show(E e){
        System.out.println("this type has extended Comparable interface");
    }
}

代码中的泛型方法参数只能为实现了Comparable接口的类,否则编译不通过。

3、泛型类

①规范

  • 泛型类的声明和非泛型类的声明类似。泛型类后面添加了类型参数声明部分。形如:class A<E>

  • 泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型

  • 注意!泛型类的类型参数不能指定在静态方法上!否则编译不通过。因为泛型的类型参数使用的前提是有该类的实例对象,在实例对象上传入泛型参数。

②实例

/**
 * @author Hanlin Wang
 */

public class GenericType {
    public static void main(String[] args) {
        A<String> a = new A<String>();
        a.show("haha");
    }
}

class A<E> {
    public void show(E e){
        System.out.println(e);
    }
}

运行结果:

haha

4、类型通配符

①规范

  • 类型通配符一般是使用?代替具体的类型参数。例如 List < ? > 在逻辑上是List< String >,List< Integer > 等所有 List< 具体类型实参 > 的父类。

  • 定义泛型类的类型形参时,不能使用“?”,只能使用“E”,“T”等形参。将泛型类作为方法的参数或在程序中使用时使用“?”作为类型通配符。

②实例

/**
 * @author Hanlin Wang
 */

public class GenericType {
    public static void main(String[] args) {
        List<String> ls = new ArrayList<String>();
        ls.add("asd");

        List<Integer> ls2 = new ArrayList<Integer>();
        ls2.add(1);

        List<Boolean> ls3 = new ArrayList<Boolean>();
        ls3.add(true);

        show(ls);
        show(ls2);
        show(ls3);
    }

    public static void show(List<?> ls){
        System.out.println(ls.get(0));
    }
}

运行结果:

asd
1
true

posted @ 2017-02-22 16:50  晚樨  阅读(157)  评论(0编辑  收藏  举报