Java之泛型基础

时间:2023-02-16 12:11:40

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, 0);
}

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

总结:

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