容器的缺点:未知类型

使用 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 时,会收到异常。

 

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

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值