考察点:JAVA泛型
(1)泛型中上界和下界的定义
上界<? extend Fruit>
下界<? super Apple>
(2)上界和下界的特点
上界的list只能get,不能add(确切地说不能add出除null之外的对象,包括Object)
下界的list只能add,不能get
(3)示例代码
java">import java.util.ArrayList;
import java.util.List;
class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
public class CovariantArrays {
public static void main(String[] args) {
//上界
List<? extends Fruit> flistTop = new ArrayList<Apple>();
flistTop.add(null);
//add Fruit对象会报错
//flist.add(new Fruit());
Fruit fruit1 = flistTop.get(0);
//下界
List<? super Apple> flistBottem = new ArrayList<Apple>();
flistBottem.add(new Apple());
flistBottem.add(new Jonathan());
//get Apple对象会报错
//Apple apple = flistBottem.get(0);
}
}
(4)上界<? extend Fruit> ,表示所有继承Fruit的子类,但是具体是哪个子类,无法确定,所以调用add的时候,要add什么类型,谁也不知道。但是get的时候,不管是什么子类,不管追溯多少辈,肯定有个父类是Fruit,所以,我都可以用最大的父类Fruit接着,也就是把所有的子类向上转型为Fruit。
下界<? super Apple>,表示Apple的所有父类,包括Fruit,一直可以追溯到老祖宗Object 。那么当我add的时候,我不能add Apple的父类,因为不能确定List里面存放的到底是哪个父类。但是我可以add Apple及其子类。因为不管我的子类是什么类型,它都可以向上转型为Apple及其所有的父类甚至转型为Object 。但是当我get的时候,Apple的父类这么多,我用什么接着呢,除了Object,其他的都接不住。
所以,归根结底可以用一句话表示,那就是编译器可以支持向上转型,但不支持向下转型。具体来讲,我可以把Apple对象赋值给Fruit的引用,但是如果把Fruit对象赋值给Apple的引用就必须得用cast。
问题内容: 我真的很难理解通配符参数。我对此有一些疑问。 作为类型参数只能在方法中使用。例如:我不能使用类型参数定义类。 我了解上限。 表示:“ 如果有实现该 接口的 对象, 则将打印。 ” 我对有点问题。表示:“ 如果具有 或扩展的任何类 (的后代 ), 则将打印。 ” 纠正我哪里出错了。 简而言之,只有或或或或可用作定义泛型类的类型参数。只能用于方法 更新1: 根据Ivor Horton的书,
在运用泛型时,类型参量常常必须使用 trait 作为限定(bound)来明确规定一个类型实现了哪些功能。例如下面的例子用到了 Display trait 来打印,所以它要求 T 由 Display 限定,也就是说 T 必须实现 Display。 // 定义一个函数 `printer`,接受一个泛型类型 `T`,其中 `T` 必须 // 实现 `Display` trait。 fn printer<
本文向大家介绍请解释一下TreeMap?相关面试题,主要包含被问及请解释一下TreeMap?时的应答技巧和注意事项,需要的朋友参考一下 考察点:key-value集合 TreeMap是一个有序的key-value集合,基于红黑树(Red-Black tree)的 NavigableMap实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序,具体取决于使用的
问题内容: 我已经阅读了数百篇有关Java中“ this”的解释,但是我真的很难理解它。我正在并行学习android和java,我知道这样做比较难,但是我很喜欢。我被杀死的一件事是“ this”。我正在粘贴下面一次使用“ this”的教程中的代码。我本打算只编写一段代码,但希望尽可能提供帮助。 我正在寻找可以添加到笔记中的“ this”的良好解释。任何和所有帮助表示赞赏。提前致谢。 示例代码从下面
问题内容: 为什么我只能使用通配符而不使用类型参数? 例如,在界面中,为什么方法不是这样写的 问题答案: super绑定命名类型参数(例如)而不是通配符(例如)是非法的,这仅仅是因为即使允许,它也不会执行你希望的操作,因为既然这是所有引用类型的最终值,一切是,实际上有没有约束。 在你的特定示例中,由于任何引用类型的数组都是(通过Java数组协方差),因此可以在编译时用作(如果这样的绑定是合法的)自
使用多重限定(multiple bounds)可以用 + 连接。和平常一样,不同的类型使用 , 隔开。 use std::fmt::{Debug, Display}; fn compare_prints<T: Debug + Display>(t: &T) { println!("Debug: `{:?}`", t); println!("Display: `{}`", t); }