java泛型

泛型

泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型

泛型也可以看成是一个变量,用来接收数据类型

泛型的标记一般用什么字母都行,但有一定的习惯:

  • E e : Element 元素
  • T t: Type 类型

一个实例

创建集合对象,使用泛型

好处:

  1. 避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
  2. 把运行期的异常(代码运行之后会抛出的异常),提升到了编译器(写代码的时候会报错)

弊端:

  1. 泛型是什么类型,就只能存储什么类型的数据

泛型的定义和使用

  • 定义一个含有泛型的类
  • 泛型是一个未知的数据类型,当我们不确定什么数据类型的时候,可以使用泛型
  • 泛型可以接收任意的数据类型,可以使用Integer,String,Student..
  • 创建对象的时候确定泛型的数据类型
1
2
3
4
5
6
7
8
9
10
11
public class DemoClass<E> {
private E name;

public E getName() {
return name;
}

public void setName(E name) {
this.name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Main {
public static void main(String[] args) {
// 不写泛型默认为Object类型
DemoClass de = new DemoClass();
de.setName("nihao");
Object obj = de.getName();
System.out.println(obj);

// 使用Integer类型
DemoClass<Integer> in = new DemoClass<>();
in.setName(1);
System.out.println(in.getName());

// 使用Double类型
DemoClass<Double> d = new DemoClass<>();
d.setName((double) 1);
System.out.println(d.getName());
}
}

定义含有泛型的方法

  • 定义含有泛型的方法:泛型定义在方法的修饰符和返回值之间

  • 格式:

    修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){

    ​ 方法体;

    }

  • 含有泛型的方法,在调用方法的时候确定泛型的数据类型

  • 传递什么类型的参数,泛型就是什么类型

1
2
3
4
5
6
7
8
public class Main2 {
public static void main(String[] args) {
genericMethod(1.000);
}
public static <M> void genericMethod(M m){
System.out.println(m);
}
}

定义和使用含有泛型的接口

含有泛型的接口:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走

就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型

1
2
3
4
5
6
7
8
public interface List<E>{
boolean add(E e);
E get(int index);
}
public class ArrayList<E> implements List<E>{
public boolean add(E e){}
public E get(int index){}
}

泛型的通配符

泛型的通配符:

  • ? :代表任意的数据类型
  • 使用方式:
    • 不能创建对象使用
    • 只能作为方法的参数使用

泛型通配符实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Main3 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
list.add(1);
list.add(2);
printArray(list);
}
// 因为我们不知道传过来的ArrayList集合元素是什么类型的,
// 可以使用泛型通配符来接收数据类型
// 泛型是在类或者方法定义的时候使用的,是类和方法的模板
// 泛型通配符是在参数具体类型未知但知道类的泛型模板的情况下使用的
public static void printArray(ArrayList<?> list) {
Iterator<?> it = list.iterator();
while(it.hasNext()){
Object o = it.next(); // it.next(): capture of ? ; 将其赋值给Object
System.out.println(o);
}
}
}

注意

  • 泛型是在类或者方法定义的时候使用的,是在定义类和方法的模板
  • 泛型通配符是在参数具体类型未知但知道类的泛型模板的情况下使用的
  • 除了定义类,接口和方法的模板,在使用时一定不能使用类似<E>的泛型,一定要具体化,当参数不知道类型的时候,无法具体化,就可以使用泛型通配符来接收
  • 创建对象的时候不能使用泛型通配符

泛型的上限限定和下限限定

  • 泛型的上限

    <E extends Number> 此类型必须是Number类型或者Number类型的子类

    泛型通配符 <? extends Number> 此参数或者变量声明的此部分类型必须是Number类型或者Number类型的子类

  • 泛型的下限

    <E super Number> 此类型必须是Number类型或者Number类型的父类

    泛型通配符 <? extends Number> 此参数或者变量声明的此部分类型必须是Number类型或者Number类型的父类


java泛型
https://blog.wangxk.cc/2020/08/29/java泛型/
作者
Mike
发布于
2020年8月29日
许可协议