Java基础(九) -- 泛型

注意事项

  • 泛型中使用的类型只能是引用类型,不能是基础数据类型。例如 int 等

    1
    ArrayList<int> ints = new ArrayList<int>(); // 错误的
  • 实例化时指定了具体的类型后,实际传入的类型可以是该类型和该类型的子类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import java.util.ArrayList;

    public class Generic {
    public static void main(String[] args) {
    ArrayList<A> list = new ArrayList<A>();
    list.add(new B());
    System.out.println(list);
    }
    }

    class A{}
    class B extends A{}
  • 泛型可以简写

    1
    ArrayList<String> strings = new ArrayList<>();
  • 不指定泛型的话默认为 Object

    自定义泛型类

  • 普通成员可以使用泛型 (属性,方法)

  • 使用泛型的数组,不能初始化

  • 静态方法中不能使用类的泛型

  • 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)

  • 如果在创建对象时,没有指定类型,默认为Object

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    @SuppressWarnings({"all"})
    public class CustomGeneric {
    public static void main(String[] args) {
    Tiger<String, Integer, Double> tiger = new Tiger<String, Integer, Double>("asdas",20,"sdasd",20.0);
    Double m = tiger.getM();
    System.out.println(m);

    // 不设置时默认为 Object
    Tiger tiger1 = new Tiger();
    // String 为 Object的子类 所以属性可以设置成功
    tiger1.setM("hello");
    Object m1 = tiger1.getM();
    System.out.println(m1);
    }
    }

    class Tiger<T,R,M>{
    String name;
    R r;
    T t;
    M m;

    public Tiger() {
    }

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

    public void setR(R r) {
    this.r = r;
    }

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

    public void setM(M m) {
    this.m = m;
    }

    public Tiger(String name, R r, T t, M m) {
    this.name = name;
    this.r = r;
    this.t = t;
    this.m = m;
    }

    public String getName() {
    return name;
    }

    public R getR() {
    return r;
    }

    public T getT() {
    return t;
    }

    public M getM() {
    return m;
    }
    }

自定义泛型接口

  • 接口中,静态成员不能使用泛型
  • 泛型接口的类型,在继承接口或者实现接口时确定
  • 没有指定类型,默认为Object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
interface IUsb<T,R>{
//T name; 不正确
public void hi(T t);

public R show();
}

interface IA extends IUsb<Boolean, Integer> {

}

class B implements IA{
@Override
public void hi(Boolean aBoolean) {

}

@Override
public Integer show() {
return null;
}
}

class A implements IUsb<String,Integer>{

@Override
public void hi(String s) {

}

@Override
public Integer show() {
return null;
}
}

自定义泛型方法

  • 泛型方法既可以定义在普通类中,也可以定义在泛型类中
  • 调用泛型方法时,编译器自动判断传入的泛型类型
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class CustomMethod_ {
    public static void main(String[] args) {
    Car car = new Car();
    car.fly("宝马",100);
    Fish<String> stringFish = new Fish<>();
    stringFish.say("hello");
    }
    }

    class Car{
    public <T,R> void fly(T t,R r){

    }
    }

    class Fish<T>{
    public <U> void swim(U u){

    }
    // 不是泛型方法,因为该方法没有定义泛型,只是使用了泛型
    public void say(T t){

    }
    }

继承和通配符

  • 泛型没有继承性

    1
    2
    List<Object> list = new ArrayList<String>(); // 不正确
    ArrayList<Object> strings = new ArrayList<>(); // 可以
  • ? 通配符,表示任意泛型;? extends AA 只接收AA或者AA的子类;? super AA 只接收AA或者AA的父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.ArrayList;
import java.util.List;

public class TongPei {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
print(strings);
ArrayList<BB> bbs = new ArrayList<>();
print1(bbs);
ArrayList<Object> objects = new ArrayList<>();
print2(objects);
}

public static void print(List<?> a){}
public static void print1(List<? extends AA> b){}
public static void print2(List<? super AA> c){}
}

class AA{}
class BB extends AA{}
class CC extends BB{}