您的位置:

Java泛型

一、泛型的作用

Java泛型(Generics)是Java SE 5中引入的一个特性,它的主要作用是参数化类型,在编译时进行类型检查,从而提高代码的安全性和可读性。

泛型的作用主要有以下几点:

1、提高代码的类型安全:使用泛型可以在编译阶段进行类型检查,从而避免因类型不匹配而引发的运行时错误。

2、简化代码的编写:使用泛型可以把类型转换的代码移到编译阶段,从而使代码更加简洁,可读性更高。

3、支持通用算法:使用泛型可以编写通用的算法,可以适用于多种不同的数据类型,提高代码的复用性和灵活性。

二、泛型的基本用法

Java泛型提供了两种定义方式:泛型类和泛型方法。

1、泛型类

泛型类是一种在类的声明中使用类型参数来表示通用类型的类,它的语法格式如下:

public class GenericClass {
    T t;
    public T getT() {
        return t;
    }
    public void setT(T t) {
        this.t = t;
    }
}

  

在上面的代码中,类名后面的<T>表示声明了一个类型参数T,通过T表示一个通用类型,在类的内部可以使用这个类型。

在使用这个泛型类时,可以用具体的类型替换T,比如:

GenericClass<String> gc = new GenericClass<>();
gc.setT("Hello World");
String str = gc.getT();

上面的代码中,使用String类型替换了T,表示泛型类只能处理String类型的数据。

2、泛型方法

泛型方法是一种在方法返回值和参数中使用类型参数来表示通用类型的方法,它的语法格式如下:

public <T> T genericMethod(T t) {
    return t;
}

在上面的代码中,<T>在方法的返回值和参数中都出现了,它们都表示的是同一个类型参数T。

在使用这个泛型方法时,可以用具体的类型替换T,比如:

String str = genericMethod("Hello World");
Integer i = genericMethod(123);

上面的代码中,第一次调用genericMethod方法时,T被替换为String类型,第二次调用时,T被替换为Integer类型。

三、泛型的高级用法

除了上面介绍的基本用法,Java泛型还提供了一些高级用法,比如通配符类型、泛型边界等。

1、通配符类型

通配符类型(Wildcard)是一种在类型参数中使用“?”来表示未知类型的类型参数,它可以用来接收任意类型的参数,但不能用来修改参数的值。

public void printList(List<?> list) {
    for (Object e : list) {
        System.out.println(e);
    }
}

在上面的代码中,List<?>表示接受一个通配符类型的List参数,可以接受任意类型的List,但不能修改List中的元素。

2、泛型边界

泛型边界(Bounds)是一种在类型参数中使用extends和super关键字来限制类型范围的方式。

extends关键字用于限制类型参数的上界,表示只能使用继承了指定类或接口的子类作为类型参数。

public class GenericClass<T extends Number> {
    T t;
    public T getT() {
        return t;
    }
    public void setT(T t) {
        this.t = t;
    }
}

在上面的代码中,使用extends关键字限制了泛型类的类型参数T必须是Number或Number的子类。

super关键字用于限制类型参数的下界,表示只能使用指定类的父类或父接口作为类型参数。

public static <T> void swap(List<? super T> list, int i, int j) {
    list.set(i, list.set(j, list.get(i)));
}

在上面的代码中,使用super关键字限制了方法的参数类型为List的父类或父接口。

四、泛型与反射

Java泛型和反射是两个互相独立的概念,但它们可以相互配合,在某些场景下使用泛型和反射可以实现更加灵活的编程。

使用反射时,可以通过Class对象获取某个类或方法的泛型信息,进而动态创建对象、调用方法等操作。

public static <T> T createInstance(Class<? extends T> clazz) throws Exception {
    Constructor<? extends T> constructor = clazz.getConstructor();
    return constructor.newInstance();
}

在上面的代码中,使用Class对象获取了指定类的无参构造方法,进而通过newInstance方法动态创建对象。

五、总结

Java泛型是一个重要的语言特性,它为Java程序员提供了一种参数化类型的声明方式,在代码编写和阅读中都起到了很大的便利作用。掌握泛型的基本用法和高级用法,可以使编码变得更加规范、安全和灵活。