Java泛型及泛型中K、T、V、E、?等的含义

泛型是Java中的一种类型系统,它可以使用一个抽象的类型来定义类、接口和方法,而无需知道这些类型的具体类型。它允许程序员以一种安全的方式定义和使用任意类型的数据。

例如:

public class Box<T> {
    private T t;
    public void add(T t) {
        this.t = t;
    }
    public T get() {
        return t;
    }
}

上述代码定义了一个Box类,它使用泛型T来定义类型,因此我们可以创建任意类型的Box对象,比如:

Box<Integer> integerBox = new Box<Integer>();
Box<String> stringBox = new Box<String>();

这样,当我们向Box中添加数据时,它就会确保添加的数据是指定类型的。

泛型中K、T、V、E、?等的含义

在定义泛型类、接口和方法时,都会定义一个参数类型,我们用过、、<K,V>等,那么这些字母有什么区别和不同呢?
定义Java的泛型时,通常使用的一些类型参数的字母或者符号有:E、T、K、V、N、?Object等。
首先,E、T、K、V、N等这些字母之间没什么区别,使用T的地方完全可以换成U、S、Z等任意字母。当然,一般我们会使用一些常用的字母,这些字符一般是一些类型的缩写。
例如:

  1. E : Element的缩写,一般在集合中使用,表示集合中的元素类型。
  2. T : Type的缩写,一般表示Java类。
  3. K : Key的缩写,一般用来表示“键”,如Map种的key。
  4. V : Value的缩写,一般用来表示“值”与K是一对。
  5. N : Number的缩写,通常用来表示数值类型。

以上这些类型其实都是确定的类型,如List表示List中的类型只能是T。
除此之外,还有不确定的类型,那就是?,<?>表示不确定的Java类型,<?>也经常出现在集合类中。
需要注意的是,在Java集合框架中,对于参数值是位置类型的容器类,只能读取其中的元素不能向其中添加元素。因为其类型是未知的,所以编译器无法识别添加元素的类型和容器的类型是否兼容,唯一的例外是null

List<?> list = new ArrayList<>();
list.add(null); //编译通过
list.add(Hollis) // 编译失败

List<?>是一个未知类型的List,不能向List<?>中添加元素,但可以把List,List赋值给List<?>。

很多人认为List<?>和List是一样的,其实这是不对的,表示任意类型,<?>表示未知类型,可以向List中添加元素,但是不能把List赋值给List。

泛型中的限定通配符和非限定通配符

假设你需要一个List来存放Fruits,那么你会定义List fruits,你能直接把List赋值给fruits吗(Apple 继承自 Fruit)?
不能
原因是List中允许添加任何水果,而List中只允许添加apple,这意味着两种类型不兼容
如果我们只关心List包含某种类型的水果这一事实,那么我们就可以使用类型通配符来定义它

public class Demo {
    public static void main(String[] args) {
        List<Apple> apples = new ArrayList<Apple>();
        List<? extends Fruits> fruits = apples;
    }
}

使用List<? extends Fruits>定义的List是可以接收List的,通过这种形式表名这是一个Fruit或者它的子类List么这意味着列表中的每个元素都是某种水果

像<? extends Fruits>这种形式,我们称之为通配符。Java泛型中有两种限定通配符。
一种是<? extends T>,保证泛型类型必须是T的子类型来设定泛型类型的上边界,即泛型类型必须为T类型或者T的子类。

public class Demo {
    public static void main(String[] args) {
        List<Apple> apples = new ArrayList<Apple>();
        List<? extends Fruits> fruits = apples;
    }
}

另一种是<? super T>保证泛型类型必须是T的父类来设定类型的下边界,即类型必须是T类型或者T的父类。

public class Demo {
    public static void main(String[] args) {
        List<Fruits> fruits = new ArrayList<>();
        List<? super Apple> apples = fruits;
    }
}
<?>是非限定通配符,表示可以用任意泛型来替代它,即可以把任意类型的List赋值给 List<?>
public class Demo {
    public static void main(String[] args) {
        List<Apple> apples = new ArrayList<Apple>();
        List<Anything> anythings = new ArrayList<>();
        List<?> fruits = apples;
        List<?> fruits = anythings;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值