1.持有对象
2.面向接口的编程思想
Map是强大的编程工具。尽管并非总是这样,但是在理想情况下,你编写的大部分代码都是在与这些接口打交道, 并且你唯一需要指定所使用的精确类型的地方就是在创建的时候。你可以像下面创建一个List:
因此,你应该创建一个具体类的对象,将其转型为对应的接口,然后在其余的代码中都使用这个接口。这种方式并非总能奏效,因为某些类具有额外的功能,例如,LinkedList具有在List接口中未包含的额外方法,而TreeMap也具有在Map接口中未包含的方法。如果你需要使用这些方法,就不能将它们向上转型为更通用的接口。
3.泛型和类型安全的容器
使用Java SE5之前的容器的一个主要问题就是编译器允许你向容器中插入不正确的类型。例如,考虑一个Apple对象的容器,我们使用最基本最可靠的容器ArrayList。现在,你可以把ArrayList当作 “可以自动扩充自身尺寸的数组” 来看待。使用ArrayList相当简单:创建一个实例,用add()插入对象,然后用get()访问这些对象,此时需要使用索引,就像数组一样,但是不需要方括号。ArrayList还有一个size()方法,使你可以知道已经有多少元素添加了进来,从而不会不小心因素引越界而引发错误。
如果我们把Apple和Orange都放置在了容器中,然后将它们取出。正常情况下,Java编译器会报告警告信息,因为没有使用泛型。Apple和Orange类是有区别的,它们除了都是Object之外没有任何共性( 如果一个类没有显式地声明继承自哪个类,那么它自动地继承自Object的)。因为 ArrayList保存的是 Object, 因此你不仅可以通过ArrayList的add()方法将Apple对象放进这个容器,还可以添加 Orange对象,而且无论在编译期还是运行时都不会有问题。
But,当你在使用ArrayList的get()方法来取出你认为是 Apple的对象时,你得到的只是 Object的引用, 必须将其转型为Apple,因此,需要将整个表边式括起来, 在调用Apple的id()方法之前,强制执行转型。否则,你就会得到语法错误。在运行时,当你试图将Orange对象转型为Apple肘,你就会以前面提及的异常的形式得到一个错误。
使用Java泛型来创建类会比较复杂。但是,应用预定义的泛型通常会很简单。例如,要想定义用来保存Apple对象的ArrayList ,你可以声明 ArrayList<Apple>,而不仅仅只是ArrayList ,其中尖括号括起来的是类型参数(可以有多个), 它指定了这个容器实例可以保存的类型。通过使用泛型, 就可以在编译期防止将错误类型的对象放置到容器中。
现在, 编译器可以阻止你将Orange放置到apples中, 因此它变成了一个编译期错误,而不再是运行时错误。 你还应该注意到, 在将元素从List中取出肘, 类型转换也不再是必需的了。 因为List知道它保存的是什么类型, 因此它会在调用get()时替你执行转型。 这样, 通过使用泛型, 你不仅知道编译器将会检查你放置到容器中的对象类型, 而且在使用容器中的对象时, 可以使用更加清晰的语法。
所有的Collection都可以用foreach语法遍历,但是被称为“迭代器”类会的更灵活。
2018-01-01 内容来自《Java编程思想》