java泛型

jasmine 于 2019-02-05 发布

泛型种类

1)泛型类

public class 类名 <泛型类型1,...> {}

示例:

//泛型类
public class GenericClass<T> {
    private T value;
    public GenericClass(T value) {
        this.value = value;
    }
    public T getValue() {
        return value;
    }
    public void setValue(T value) {
        this.value = value;
    }
}

//测试类
GenericClass<String> name = new GenericClass<>("哈哈");
System.out.println(name.getValue());

GenericClass<Integer> number = new GenericClass<>(123);
System.out.println(number.getValue());

2)泛型接口

public interface 接口名 <泛型类型1,...> {}

示例:

public interface GenericInterface<T> {
    void show(T value);
}
 
public class StringShowImpl implements GenericInterface<String> {
@Override
    public void show(String value) {
        System.out.println(value);
    }
}
 
public class NumberShowImpl implements GenericInterface<Integer> {
@Override
    public void show(Integer value) {
        System.out.println(value);
    }
}

3)泛型方法

public <泛型类型> 返回类型 方法名泛型类型 变量名 {}

注意要点: 方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。当调用fun()方法时,根据传入的实际对象,编译器就会判断出类型形参T所代表的实际类型。

public <T> T genercMethod(T t){
    System.out.println(t.getClass());
    System.out.println(t);
    return t;
}

泛型通配符

无界通配符

”?” 用于方法形参 比如我们在 无界通配符 “?” 的代码示例,即使不在泛型类中,”?” 也可以作为方法形参,定义方法返回值等,但是我们不能对 “?” 进行单独定义、操作

示例1:

private List<?> list;
private ? data;//报错
public class OrderRequest<?> {}//报错
public void test(? item){}//报错

示例2:

static int countLegs (List<? extends Animal > animals ) {
    int retVal = 0;
    for ( Animal animal : animals )
    {
        retVal += animal.countLegs();
    }
    return retVal;
}

static int countLegs1 (List< Animal > animals ){
    int retVal = 0;
    for ( Animal animal : animals )
    {
        retVal += animal.countLegs();
    }
    return retVal;
}

public static void main(String[] args) {
    List<Dog> dogs = new ArrayList<>();
     // 不会报错
    countLegs( dogs );
    // 报错
    countLegs1(dogs);
}

注意:

1)类型参数可以多重限定而通配符不行 2)通配符可以使用超类限定而类型参数不行

类型参数 T 只具有 一种 类型限定方式

T extends A
但是通配符 ? 可以进行 两种限定

? extends A
? super A

泛型上下边界

// 1:表示类型参数可以是任何类型
public class Apple<?>{} 
// 2:表示类型参数必须是A或者是A的子类
public class Apple<T extends A>{} 
// 3: 表示类型参数必须是A或者是A的超类型
public class Apple<T supers A>{}

泛型擦除

1)普通类型

替换为Object

//普通泛型
public class Caculate<T> {
    private T num;
}
//类型擦除后
public class Caculate{
    public Caculate(){}
    private Object num;
}

2)有上界情况
替换为上界类型