天天看点

Java之泛型基础java之泛型基础

java之泛型基础

一:简介

从这里开始再次回顾一下java基础,目的是再次深入一点学习,不是教程,主要以相关知识的重点为主,有时候可能有较强的偏向性,所以可能会遗漏一些基础概念或者之类的东西。泛型学习笔记上篇,主要记录java泛型相关基础,包括为什么引入泛型,泛型的使用方式,以及在JDK或框架中的典型应用。

二:泛型的概念

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

三:为什么要使用泛型

  • 类型安全—— 泛型的主要目标是提高 Java 程序的类型安全。使得java代码可以编译时期检查出因java类型导致的可能在运行时抛出ClassCastException异常。符合越早出错代价越小原则。
  • 消除强制类型转换—— 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
  • 潜在的性能收益—— 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

四:泛型语法

如在概念中提到,参数化类型可以用在类、接口、方法上。

泛型类:

public class GenericClass<T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
           

泛型接口

public interface GenericInterface<T> {
    void method(T t);
}
           

泛型方法

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

五:典型应用

关于泛型,我们最常见的就是在JDK的集合中见到,并且使用。简单的看一个典型的集合类:Collection。
           
public interface Collection<E> extends Iterable<E> {
    // Query Operations

    int size();

    boolean isEmpty();

    boolean contains(Object o);

    Iterator<E> iterator();

    Object[] toArray();

    <T> T[] toArray(T[] a);

    // Modification Operations

    boolean add(E e);

    boolean remove(Object o);


    // Bulk Operations

    boolean containsAll(Collection<?> c);

    boolean addAll(Collection<? extends E> c);

    boolean removeAll(Collection<?> c);

    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    boolean retainAll(Collection<?> c);

    void clear();


    // Comparison and hashing

    boolean equals(Object o);

    int hashCode();

    /**
     * default 关键字是java1.8引入的一个新特性,有兴趣的可以自行了解一下
     * 相关的Spliterator和Stream以及前面的Predicate都是1.8新引入的接口
     */

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, );
    }

    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}
           

从Spring的BeanFactory中获取Bean的方法

<T> T getBean(String name, Class<T> requiredType) throws BeansException;
           

泛型使用规则

  1. 泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
  2. 同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
  3. 泛型的类型参数可以有多个。
  4. 泛型的参数类型可以使用extends语句,例如。习惯上称为“有界类型”。
  5. 泛型的参数类型还可以是通配符类型。例如Class

总结:

这里只记录了泛型最基本的一些知识,连泛型的边界都没有涉及到,目的是想让结构清晰一点。接下来的泛型进阶,和泛型最佳实战会深入了解。