容器的缺点:未知类型

使用 Java 容器有个“缺点”,在将对象加入容器的时候就丢失了类型信息。因为使用容器
的程序员不关心你想要添入容器的对象的具体类型。如果容器只能保存你自己的类型,就
失去了作为通用工具的意义。所以容器只保存 Object 型的引用,这是所有类的基类,因此
容器可以保存任何类型的对象。(当然不包括基本类型,因为它们不是真正的对象,没有
继承任何东西。)这是了不起的解决方式,不过:


1. 因为在你将对象的引用加入容器时就丢失了类型的信息,所以对于添入容器的对
象没有类型限制,即使你刻意保持容器的类型,例如类型“猫”的容器。别人还
是可以轻易将“狗”放入容器。
2. 因为丢失了类型信息,容器只知道它保存的是 Object 类型的引用。在使用容器
中的元素前必须要做类型转换操作。


好在 Java 并不会让你误用容器中的对象。如果你将“狗”丢入存放“猫”的容器,然后将
其中的每件东西都作为“猫”,当你将指向“狗”的引用取出容器,类型转换为“猫”时
会收到 RuntimeException 异常。


下面的例子用到了最基本、最常用的容器ArrayList。对于初学者,你可以将ArrayList看
作是“能够自动扩展的数组”。ArrayList用起来很方便:创建一个ArrayList,使用add()
 






添加对象,使用get()和索引取出对象——就像数组那样,只是不使用方括号7。ArrayList
也有size()方法,可以告诉你容器中有多少元素,使你不至于超过边界而引发异常。


首先,创建 Cat 类和 Dog 类:


//: c11:Cat.java
package c11; 


public class Cat { 
private int catNumber;
public Cat(int i) { catNumber = i; } 
public void id() {
    System.out.println("Cat #" + catNumber);
  }
} ///:~








//: c11:Dog.java
package c11; 


public class Dog { 
private int dogNumber;
public Dog(int i) { dogNumber = i; } 
public void id() {
    System.out.println("Dog #" + dogNumber);
  }
} ///:~


Cat 和 Dog 被添入容器,然后再取出来:


//: c11:CatsAndDogs.java
// Simple container example.
// {ThrowsException}
package c11; 
import java.util.*; 


public class CatsAndDogs { 
public static void main(String[] args) { 
    List cats = new ArrayList();
for(int i = 0; i < 7; i++)
      cats.add(new Cat(i)); 

// Not a problem to add a dog to cats:

   cats.add(new Dog(7));

for(int i = 0; i < cats.size(); i++)

      ((Cat)cats.get(i)).id();

// Dog isdetected only at run time

  }

}   ///:~

 

Cat 与 Dog 是不同的类:除了都是 Object 的子类,它们之间没有相同之处。(如果不明

确地指出你的类从何处继承而来,则自动继承自 Object)因为 ArrayList 保存 Object,

所以你不仅可以用ArrayList 的 add()方法将 Cat 添入容器,也可以将 Dog 添入同一个容

器而不会引起任何编译期或运行期错误。当你使用 get()方法从 ArrayList 中取出你以为是

Cat 的元素时,得到的只是 Object 的引用,需要做类型转换为 Cat。于是使用圆括号将整

个表达式括住,强迫做类型转换,才能使用 Cat 的方法 id()。否则是一个语法错误。在程

序运行的时候,当你将 Dog 对象作类型转换为 Cat 时,会收到异常。

 

这不只是个小麻烦,它有可能造成很难发现的错误。如果程序在某处(或多处)向容器插

入对象,而在程序的另一处捕获到异常,发现有错误的对象被置入容器,然后你必须找出

这个错误的插入是在哪里发生的。多数时候这并不是严重问题,但你应该留意这种可能性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值