一、Java基础(4)

本章概要

  • 泛型
    • 泛型标记和泛型限定
    • 泛型方法
    • 泛型接口
    • 类型擦除

1.6 泛型

泛型是参数化类型,提供了编译时类型的安全检测机制,该机制允许程序在编译时检测非法的类型,比如要实现一个能够对字符串(String)、整数型(Int)、浮点型(Float)、对象(Object)进行大小比较的方法,就可以使用泛型。
在不使用泛型的情况下,可以通过引用 Object 类型来实现参数的任意化,因为在 Java 中,Object 类是所有类的父类,但在具体使用时需要进行强制类型转换。在进行强制类型转换时,开发者必须明确知道实际参数的引用类型,不然可能引起强制类型转换错误,在编译期无法识别这种错误,只能在运行期检测这种错误(即只有在程序运行出错时才能发现该错误)。
而使用泛型的好处是在编译期就能够检测类型是否安全,同时所有强制性类型转换都是自动和隐式进行的,提高了代码的安全性和重用性。

1.6.1 泛型标记和泛型限定

在使用泛型前首先要了解有哪些泛型标记,如下:

泛型标记 说明
E-Element 在集合中使用,表示在集合中存放的元素
T-Type 表示 Java 类,包括基本的类和我们自定义的类
K-Key 表示键,比如 Map 中的 Key
V-Value 表示值
N-Number 表示数值类型
? 表示不确定的 Java 类型

类型通配符使用“?”表示所有具体的参数类型,例如 List 在逻辑上是 List、List 等所有 List<具体类型实参> 的父类。
在使用泛型时,如果希望将类的继承关系加入泛型应用中,就需要对泛型做限定,具体的泛型限定有对泛型上限的限定和对泛型下限的限定。

  1. 对泛型上限的限定:

在 Java 中使用通配符“?”和“extends”关键字限定泛型的上限,具体用法为 ,它表示该通配符所代表的类型是 T 类的子类或接口 T 的子接口。

  1. 对泛型下限的限定:

在 Java 中使用通配符“?”和“super”关键字限定泛型的下限,具体用法为 ,表示该通配符所代表的的类型是 T 类型的父类或父接口。

1.6.2 泛型方法

泛型方法指将方法的参数类型定义为泛型,以便在调用时接收不同类型的参数。在方法的内部根据传递给泛型方法的不同参数类型执行不同的处理方法,具体用法如下:

public class GeneralClass<T> {
    public static void main(String[] args) {
        //根据需求初始化不同的类型
        GeneralClass<Integer> genInt = new GeneralClass<Integer>();
        genInt.setT(1);
        GeneralClass<String> genStr = new GeneralClass<String>();
        genStr.setT("1");
    }

    private T t;

    public T getT() {
        return t;
    }

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

在以上代码中通过 public class GeneralClass{} 定义了一个泛型类,可根据不同的需求参数化不同类型(参数化类型指编译器可以自动定制作用于特定类型的类),比如参数化一个字符串子类的泛型类对象;

new GeneralClass<String>();

1.6.4 泛型接口

泛型接口的声明和泛型类的声明类似,通过在该接口名后面添加类型参数的声明部分来实现。泛型接口的具体类型一般都在实现类中声明,不同类型的实现类处理不同的业务逻辑。

public interface IGeneral<T> {

    public T getId();

}
public class IGeneralIntegerImpl implements IGeneral<Integer> {
    @Override
    public Integer getId() {
        Random random = new Random(100);
        return random.nextInt();
    }

    public static void main(String[] args) {
        //使用泛型
        IGeneralIntegerImpl generalInteger = new IGeneralIntegerImpl();
        System.out.println(generalInteger.getId());
    }
}

以上代码通过 public interface IGeneral{} 定义了一个泛型接口,并通过 public class IGeneralIntegerImpl implements IGeneral{} 定义了一个 Integer 类型的实现类。

1.6.5 类型擦除

在编码阶段使用泛型时加上的类型参数,会被编译器在编译时去掉,这个过程就被称为类型擦除。因此泛型主要用于编译阶段。
在编译后生成的 Java 字节代码文件中不包含泛型中的类型信息。例如,在编码时定义的 List 和 List 经过编译后统一为 List。 JVM 所读取的只是 List ,由泛型附加的类型信息对 JVM 来说是不可见的。
Java 类型的擦除过程:首先,查找用于替换类型参数的具体类(该具体类一般为 Object),如果指定了类型参数的上界,则以该上界作为替换时的具体类;然后,把代码中的类型参数都替换为具体的类。
相关面试题:

  • Java 中的泛型是什么?使用泛型的好处是什么?★★★☆☆
  • 常用的泛型标记有哪些?★★☆☆☆
  • 什么是类型擦除?★★☆☆☆
  • 如何在类上使用泛型?★☆☆☆☆

你可能感兴趣的:(Offer,泛型,泛型标记和泛型限定,泛型方法,泛型接口,类型擦除)