专栏名称: java一日一条
主要是讲解编程语言java,并且每天都推送一条关于java编程语言的信息
目录
相关文章推荐
芋道源码  ·  能在一家不到 20 人的 IT ... ·  18 小时前  
芋道源码  ·  30K ... ·  昨天  
芋道源码  ·  Guava黑魔法:在日志脱敏场景下的奇遇 ·  昨天  
51好读  ›  专栏  ›  java一日一条

Java 泛型详解

java一日一条  · 公众号  · Java  · 2017-11-16 09:58

正文

请到「今天看啥」查看全文


通配符

在了解通配符之前,我们首先必须要澄清一个概念,还是借用我们上面定义的Box类,假设我们添加一个这样的方法:

那么现在 Box n 允许接受什么类型的参数?我们是否能够传入 Box 或者 Box 呢?答案是否定的,虽然Integer和Double是Number的子类,但是在泛型中 Box 或者 Box Box 之间并没有任何的关系。这一点非常重要,接下来我们通过一个完整的例子来加深一下理解。

首先我们先定义几个简单的类,下面我们将用到它:

下面这个例子中,我们创建了一个泛型类 Reader ,然后在 f1() 中当我们尝试 Fruit f = fruitReader.readExact(apples); 编译器会报错,因为 List List 之间并没有任何的关系。

但是按照我们通常的思维习惯,Apple和Fruit之间肯定是存在联系,然而编译器却无法识别,那怎么在泛型代码中解决这个问题呢?我们可以通过使用通配符来解决这个问题:

这样就相当与告诉编译器, fruitReader的readCovariant方法接受的参数只要是满足Fruit的子类就行(包括Fruit自身),这样子类和父类之间的关系也就关联上了。

PECS原则

上面我们看到了类似 extends T> 的用法,利用它我们可以从list里面get元素,那么我们可不可以往list里面add元素呢?我们来尝试一下:

答案是否定,Java编译器不允许我们这样做,为什么呢?对于这个问题我们不妨从编译器的角度去考虑。因为 List extends Fruit> flist 它自身可以有多种含义:

  • 当我们尝试add一个Apple的时候,flist可能指向 new ArrayList () ;

  • 当我们尝试add一个Orange的时候,flist可能指向 new ArrayList () ;

  • 当我们尝试add一个Fruit的时候,这个Fruit可以是任何类型的Fruit,而flist可能只想某种特定类型的Fruit,编译器无法识别所以会报错。







请到「今天看啥」查看全文