---
url: /notes/java-se/泛型/index.md
---
# 泛型

创建集合时，如果**不指定类型**

1. 存储的类型为Object，可用存储任意的值

2. 不安全，可能发生类型转换异常

```java
ArrayList list=new ArrayList();
list.add(1);
list.add("u");
for (Object o : list) {
    Integer.parseInt((String) o);
}
```

![image-20211124224008062](https://note-1259190304.cos.ap-chengdu.myqcloud.com/note/202111271740957.png)

创建集合时，

**使用泛型**

1. 避免类型转换

2. 可在编译期时检查异常

3. 类型固定，只能存储对应类型的数据

## 泛型里的通配符

`?` 表示任意的数据类型

**使用方式：**

1. 不能创建对象的时候使用，只能作为方法的参数

2. 不能定义到类上

3. 当我们不知道用什么类型来接收的时候，可使用`?`，作为通配符，来表示未知的

```java
public static void main(String[] args) {
        Collection<String> coll=new ArrayList<>();
        getElement(coll);
}
public static void getElement(Collection<?> coll){
     
}
```

```java
//错误，通配符 ? 不能定义到类上
class Person<?>{
    void method(){

    }
}
```

### 受限泛型

可以指定泛型的上限和下限

#### 泛型上限格式

```java
类型名称<? extends 类>对象名称
```

只能接收**该类型和其子类**

#### 泛型下限格式

```java
类型名称<? super 类>对象名称
```

只能接收**该类型** 和其**父类**

```java
//Human类
public class Human {
}

//Person类 继承于Human类
public abstract class Person extends Human {
    abstract void method(Collection<? extends Person> coll);

    abstract void methodA(Collection<? super Person> coll);
}

//Student类 继承于 Person
public class Student extends Person {
    @Override
    void method(Collection<? extends Person> coll) {
        System.out.println("hello");
    }

    @Override
    void methodA(Collection<? super Person> coll) {
        System.out.println("world");
    }
}

public static void main(String[] args) {
    Person person=new Student();
    Collection<Person> coll=new ArrayList();
    Collection<Student> coll2=new ArrayList();
    Collection<Human> coll3=new ArrayList();
    person.method(coll);
    person.method(coll2);
//    person.method(coll3); Collection只能接受Person和子类

     person.methodA(coll);
//    person.methodA(coll2); 只能接受Person和父类
     person.methodA(coll3);
}
```

## 泛型定义类

在定义**类** 的时候使用`E`：表示任意类型

### 泛型类定义格式

```java
// E
修饰符 class 类名称<泛型>{}
```

**为什么使用？** 在创建对象时，不知道使用什么类型，需要定义一个泛型

```java
public class DemoClass {
    public static void main(String[] args) {
        GenirecClass<String> gc=new GenirecClass<>("扎三");
    }
}
class GenirecClass<E> {
    private E name;

    public E getName() {
        return name;
    }

    public void setName(E name) {
        this.name = name;
    }

    public GenirecClass(E name) {
        this.name = name;
    }
}
```

## 泛型方法定义格式

```java
// T
修饰符 <泛型类型> 返回值类型 方法名(参数){}
```

## 接口泛型

在定义**接口** 的时候使用`I`：表示任意类型

### 泛型接口定义格式

```java
// <I>
修饰符 interface 接口名称<泛型>{}
```

```java
public interface DemoInterface<I> {
    void method(I name);
    I method();
}
public class DemoInterfaceImpl implements DemoInterface<String>{
    @Override
    public void method(String name) {
    }
}
```

## 带有通配符的泛型

当使用**泛型类** 或者**接口** ，传递数据时，**泛型类型不确定** ，可以使用`<?>`表示
