服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

下溯造型与运行期类型标识


  由于我们在上溯造型(在继承结构中向上移动)期间丢失了具体的类型信息,所以为了获取具体的类型信息――亦即在分级结构中向下移动――我们必须使用 “下溯造型”技术。然而,我们知道一个上溯造型肯定是安全的;基础类不可能再拥有一个比衍生类更大的接口。因此,我们通过基础类接口发送的每一条消息都肯定能够接收到。但在进行下溯造型的时候,我们(举个例子来说)并不真的知道一个几何形状实际是一个圆,它完全可能是一个三角形、方形或者其他形状。
  
下溯造型与运行期类型标识


  为解决这个问题,必须有一种办法能够保证下溯造型正确进行。只有这样,我们才不会冒然造型成一种错误的类型,然后发出一条对象不可能收到的消息。这样做是非常不安全的。
  
  在某些语言中(如c++),为了进行保证“类型安全”的下溯造型,必须采取特殊的操作。但在java中,所有造型都会自动得到检查和核实!所以即使我们只是进行一次普通的括弧造型,进入运行期以后,仍然会毫无留情地对这个造型进行检查,保证它的确是我们希望的那种类型。如果不是,就会得到一个classcastexception(类造型违例)。在运行期间对类型进行检查的行为叫作“运行期类型标识”(rtti)。下面这个例子向大家演示了rtti的行为:
  
  //: rtti.java
  // downcasting & run-time type
  // identification (rtti)
  import java.util.*;
  
  class useful {
   public void f() {}
   public void g() {}
  }
  
  class moreuseful extends useful {
   public void f() {}
   public void g() {}
   public void u() {}
   public void v() {}
   public void w() {}
  }
  
  public class rtti {
   public static void main(string[] args) {
  useful[] x = {
   new useful(),
   new moreuseful()
  };
  x[0].f();
  x[1].g();
  // compile-time: method not found in useful:
  //! x[1].u();
  ((moreuseful)x[1]).u(); // downcast/rtti
  ((moreuseful)x[0]).u(); // exception thrown
   }
  } ///:~
  
  和在示意图中一样,moreuseful(更有用的)对useful(有用的)的接口进行了扩展。但由于它是继承来的,所以也能上溯造型到一个useful。我们可看到这会在对数组x(位于main()中)进行初始化的时候发生。由于数组中的两个对象都属于useful类,所以可将f()和g()方法同时发给它们两个。而且假如试图调用u()(它只存在于moreuseful),就会收到一条编译期出错提示。
  
  若想访问一个moreuseful对象的扩展接口,可试着进行下溯造型。如果它是正确的类型,这一行动就会成功。否则,就会得到一个classcastexception。我们不必为这个违例编写任何特殊的代码,因为它指出的是一个可能在程序中任何地方发生的一个编程错误。
  
  rtti的意义远不仅仅反映在造型处理上。例如,在试图下溯造型之前,可通过一种方法了解自己处理的是什么类型。整个第11章都在讲述java运行期类型标识的方方面面。

扫描关注微信公众号