JavaSE基础复习六:泛型

本文最后更新于:2021年7月23日 晚上


JavaSE基础复习六:泛型

泛型

泛型是JDK5中引入的特性,他提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型

  • 本质:参数化类型,也就是说所操作的数据类型被指定为一个参数。顾名思义,将类型由原来的具体的类型参数化,然后在使用、调用是传入具体的类型

  • 可以使用的地方:可以用在类、方法和接口中,分别被称为泛型类、泛型方法和泛型接口

  • 定义格式:

    • <类型>:指定一种类型的格式

    • <类型1,类型2..>:指定多种类型的格式

    多种类型之间用逗号隔开。这里的类型可以看成是形参,将来具体调用时候给定的类型可以看成是实参,并且只能是引用数据类型

  • 泛型的优点:

    • 吧运行时期的问题提前到了编译期间
    • 避免了强制类型转换

泛型使用方法

  • 泛型类

    1
    2
    3
    修饰符 class 类名<类型> {}

    public class Generic<T> {}
  • 泛型方法

    1
    2
    3
    修饰符 <类型> 返回值类型 方法名(类型 变量名) {...}

    public <T> void show(T t) {}

    此时的T可以是任意引用类型,实际开发中一般不会这么使用,一般会用extends和super关键字限定类型

  • 泛型接口

    1
    2
    3
    修饰符 interface 接口名<类型> {}

    public interface Generic<T> {}

类型通配符

  • 类型通配符:<?>
    • List<?>:表示元素类型位置的List,他的元素可以匹配任何的类型
    • 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
  • 类型通配符的上限:<? extends 类型>
    • List<? extends Number>:它表示的类型是Number或其子类型
  • 类型通配符的下限:<? super 类型>
    • List<? Super Number>: 它表示的类型是Number或其父类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
List<?> list = new ArrayList<Object>();
List<?> list1 = new ArrayList<Number>();
List<?> list2 = new ArrayList<Integer>();

System.out.println("--------");
// List<? extends Number> list3 = new ArrayList<Object>(); // 报错,Object不是Number的子类型
List<?> list4 = new ArrayList<Integer>();
List<?> list5 = new ArrayList<Number>();

System.out.println("--------");
List<? super Number> list6 = new ArrayList<Object>();
List<? super Number> list7 = new ArrayList<Number>();
// List<? super Number> list8 = new ArrayList<Integer>; // 报错,Integer不是Number的父类

可变参数

可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了

  • 原理:将传入的多个参数封装为了一个数组

  • 格式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    修饰符 返回值类型 方法名(数据类型... 变量名) {}

    public static int sum(int... a) {
    int sum = 0;
    for (int n : a) {
    sum += n;
    }
    return sum;
    }
  • 注意:

    • 如果一个方法有多个参数,那么可变参数一定要写到最后

      1
      2
      3
      4
      5
      6
      7
      public static void sum(String a, int b, int... c) {
      System.out.println(a);
      System.out.println(b);
      for (int num : c) {
      System.out.println(num);
      }
      }
    • 当有方法重载,优先使用确定参数个数的方法,如果没有再使用可变参数的方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      public static int sum(int... a) {
      int sum = 0;
      for (int n : a) {
      sum += n;
      }
      return sum;
      }

      public static int sum(int a, int b, int c) { // 当传入三个int参数时,优先使用此方法
      return a+b+c;
      }

      public static int sum(int a, int b){ // 当传入两个int参数时,优先使用此方法
      return a+b;
      }
  • 常用的方法:

    • Arrays工具类中:public static <T> List<T> asList(T... a),返回由指定数组支持的固定大小的列表
    • List接口中:public static <E> List<E> of(E... elements),返回包含任意数量元素的不可变列表
    • Set接口中:public static <E> Set<E> of(E... elements),返回一个包含任意数量元素的不可变集合

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!