JavaSE之泛型

泛型

类中的泛型

public class Person<A> {
    private String name;
    private int age;
    private A data;
    
    ... 
        
    public A getData() {
        return data;
    }

    public void setData(A data) {
        this.data = data;
    }
}

public class Demo1 {
    public static void main(String[] args) {
        Person<String> p = new Person<>();
        p.setData("123");
    }
}

接口中的泛型

public interface Function<T> {
    T a();
}

实现时可以指定或不指定泛型:

// 指定
public class Imp implements Function<String>{
    @Override
    public String a() {
        return null;
    }
}
// 不指定
class Imp2<T> implements Function<T>{
    @Override
    public T a() {
        return null;
    }
}

方法中的泛型

public class Fx {
	// 泛型声明<T>,该泛型只能在方法中使用
    // 参数包含T泛型:
    public <T> void abc(T a){
        return;
    }
	// 返回值为T泛型:
    public <T> T asd(){
        T a = null;
        return a;
    }
}

泛型限制类型

public class Demo2 {
    public static void main(String[] args) {
        // 需求:盘子里面只能放水果,泛型限制:
        Plate<Fruit> fruitPlate = new Plate<>();
    }
}
interface Fruit{}

class Apple implements Fruit{}

// 盘子类,使用 extends 限制泛型
class Plate<T extends Fruit>{
    T[] data;
}

泛型通配符

使用泛型时,也能限制泛型:

public class Demo2 {
    public static void main(String[] args) {
        // 需求:盘子里面只能放水果,泛型限制:
        Plate<Fruit> fruitPlate = new Plate<>();

        // 不能将一个装着苹果的盘子,看成一个装着水果的盘子
        // 原因:多态是基于继承的,需要子父类的关系,
        // 而泛型是类内部的属性,这句赋值依然还是盘子类!
//        Plate<Fruit> p = new Plate<Apple>();

        // 如果需要这样的逻辑,就应该使用通配符:
        Plate<? extends Fruit> p2 = new Plate<Apple>();

        // 除了限制类上界,另外也能限制下界:
        Plate<? super Apple> p3 = new Plate<Fruit>();

        // ? 可以当做Object看待,但实际?是替换,该是什么类型就是什么类型,确定了一个就不能用其他类型了:
        // 实际上?就相当于? extends Object
        Plate<?> p4 = new Plate<>();
        
        // 泛型的原理实际上就是 编译完成后替换成对应的类,编译成源码时所有泛型都是替换掉了一个Object
        // 所以泛型不能放基本数据类型,只能放对象:
//        Number<int> p5 = new Number<>();
        Number<Integer> p5 = new Number<>();

    }
}
interface Fruit{}
class Apple implements Fruit{}
// 盘子类,使用 extends 限制泛型
class Plate<T extends Fruit>{
    T[] data;
}
class Number<T>{
    T[] data;
}

另外通配符联系List等数据结构也有一些限制,比如:

无法从 Arraylist<? extends T> 这样类型的 list对象中存数据add(),但可以取出、修改数据,并可以将一个list赋值给他;

无法从 Arraylist<? super T> 这样类型的 list对象中取出数据,但可以存数据,同样也可以再次赋值list;

这样设计的作用主要是为了安全的操作数组,保证某些情况下list的数据不会因为意外丢失,可以满足某些不允许删改数据的情况。

举例来说比如用来复制数组,详见java.util.Collections的copy方法。

比较偏的知识点,不用太深究,不记得也没太大关系,大体上很少用到通配符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值