`

[#0x000C] 有关向下转型的必要性和动态绑定的细节

    博客分类:
  • Java
阅读更多

  在[#0x0009]里面说过,“除了static方法和final方法(final包含private)外,Java对其他所有的方法都采用dynamic binding”(P151, Chapter 8, Thinking in Java, Fourth Edition),不过下面的这个例子也许会让人有点吃惊(adapted from Chapter 8, Thinking in Java, Fourth Edition):

//@file RTTI.java
//RTTI: Run-Time Type Identification

class Useful 
{
	public void f() {System.out.println("Useful.f()");}
}

class MoreUseful extends Useful 
{
	public void f() {System.out.println("MoreUseful.f()");}
	public void g() {System.out.println("MoreUseful.g()");}
}	

public class RTTI 
{
	public static void main(String[] args) 
	{
		Useful x = new MoreUseful();
		
		x.f();
		//x.g();//编译错误:找不到符号
		((MoreUseful)x).g(); // Downcast/RTTI
	}
}
//output:
/*
	MoreUseful.f()
	MoreUseful.g()
*/

  按理来说,x.f()通过动态绑定能够正确调用MoreUseful的f()方法,那么为什么x.g()就不行呢?真的是“除了static方法和final方法(final包含private)外,Java对其他‘所有’的方法都采用dynamic binding”吗?还是只对覆写方法才动态绑定?

  其实这里涉及到动态绑定的细节问题。当然,的确是“除了static方法和final方法(final包含private)外,Java对其他所有的方法都采用dynamic binding”,只不过在使用动态绑定之前,编译器还做了一些其他的工作,而这些工作,就是造成上面代码结果的原因。

  Java的方法调用过程:

  ->编译器查看引用(x)的声明类型(Useful)和方法名(g());

    -->通过声明类型找到方法列表;

      ---->如果方法名不在方法列表中,则编译器报错(g()不在Useful的方法列表里,所以出错);

      ---->如果方法名在方法列表中,则继续下列步骤;

  ->编译器查看方法的参数列表,获取参数方法签名;

    -->如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法(这是静态绑定);

    -->如果不是上述情况,就要使用动态绑定;

  可见,x.g()出错是由于使用动态绑定前的方法名检查未通过。从这个角度来说,动态绑定似乎的确只适用于覆写方法。

  由于无法使用动态绑定,所以要正确调用x.g()方法,向下转型((MoreUseful)x)就必不可少了。这里x必须指向一个实际的MoreUseful对象(即是通过向上转型得来),如果Useful x = new Useful(),那么((MoreUseful)x)会编译报错。

分享到:
评论

相关推荐

    电脑蓝屏代码一览表 有助于 你更好的了解你的电脑为什们蓝屏啊!

    根据提供的标题、描述以及部分代码内容,我们可以详细探讨与电脑蓝屏相关的常见错误代码及其含义。这将有助于用户更好地理解导致计算机出现蓝屏的具体原因。 ### 0x0000 - 未知错误 通常表示系统遇到无法识别的...

    常见蓝屏代码,代码蓝屏

    为了帮助用户更好地理解和解决这些问题,本文将详细介绍一系列常见的蓝屏错误代码及其含义。 #### 0x00000000 - 未知错误 此错误代码通常表示未知或未定义的系统错误。 #### 0x00000001 - 初始化失败 当系统初始化...

    Windows 错误码整理

    ### 0x000C - 数据错误。 这通常是因为数据损坏或格式不正确,导致无法正确解析或处理。 ### 0x000D - 设备未准备好。 此错误表明设备(如硬盘驱动器或网络连接)尚未准备好接收请求。 ### 0x000E - 文件名太长。 ...

    Windows xp 蓝屏代码详解

    #### 0x000C - 数据不可用 - **描述**:请求的数据当前不可用。 - **可能原因**:数据正在被其他进程使用。 #### 0x000D - 错误过大 - **描述**:错误超出了预期范围。 - **可能原因**:系统资源管理错误。 #### ...

    windows蓝屏代码

    #### 0x0000000C 存取码错误 如果存取码错误,则表示对某个资源的访问方式不正确,可能是读写权限不匹配。 #### 0x0000000D 资料错误 该错误表示数据本身存在问题,例如数据损坏或格式不正确。 #### 0x0000000E ...

    电脑蓝屏代码大全

    检查文件路径和文件完整性是解决问题的关键。 ##### 0X0000003 系统找不到指定的路径 与0X0000002类似,但更侧重于路径本身的问题。确保路径正确无误非常重要,尤其是对于系统文件和程序路径。 ##### 0X0000004 ...

    蓝屏错误对照表

    - **解决方案**:检查设备兼容性和驱动程序版本。 #### 0x00000017:资料错误(Cyclic Redundancy Check)。 - **描述**:数据传输过程中出现CRC校验错误。 - **解决方案**:检查硬盘或存储设备是否有坏道,使用磁盘...

    TaiXuan91#TXLuaLesson#0X2B循环for1

    0X2B循环for前置知识0X29再谈循环正文Lua除了while和repeat语句还提供了一种for循环语句.while和repeat语句循环终止条件可以是任

    windows蓝屏错误代码大全

    在Windows操作系统中,遇到系统崩溃的情况时,通常会出现所谓的“蓝屏死机”(Blue Screen of Death, BSOD),此时屏幕上会显示一个蓝色背景的信息页面,包含了一些技术细节和一个错误代码。这些错误代码对于诊断...

    TartaricAcid#TXLuaLesson#0X0E中学算术1

    0X0E中学算术前置知识0X0D数学库函数正文有了三角函数、反三角函数、对数函数、求幂运算,中学阶段涉及的所有具体的数值计算基本就都可以求解。求此表达式的值:第

    TaiXuan91#TXLuaLesson#0X36度量时间1

    1. 度量脚本执行时间 2. 记录时间 3. 计算时间间隔

    蓝屏代码解析。欢迎下载。

    - **0x000a**: 内核模式下的异常情况。 #### 0x000b - 0x0010 - **0x000b**: 一个设备驱动程序尝试执行不支持的操作。 - **0x000c**: 无法成功获取指定资源。 - **0x000d**: 设备驱动程序或服务存在严重错误。 - *...

    windows蓝屏错误代码小解

    ### 12 0x0000000C 设备类型未找到 此错误表示尝试访问的设备类型在系统中不可识别。可能是硬件驱动程序出现问题所致。 ### 13 0x0000000D 请求的命令无法执行 如果系统无法执行发送给它的指令,则会返回此错误代码...

    ARM7_test4.rar_keil4怎样编arm程序?

    在Keil uVision4环境下编写基于ARM7处理器的程序,主要涉及的知识点包括Keil集成开发环境的使用、ARM汇编语言编程以及定时器的配置和应用。以下将详细阐述这些内容。 首先,Keil uVision4是一款强大的嵌入式系统...

    real6410点灯

    根据提供的信息,我们可以了解到这是一段与 real6410 开发板相关的代码,主要涉及了点亮 LED(点灯)的操作。此操作是在 U-Boot(一个常用的嵌入式设备启动加载程序)环境下进行的。下面我们将从以下几个方面对这段...

    彻底搞清回车(0x0d)和换行(0x0a)

    在 Windows XP Visual C++下,按下回车键,系统获得的字符是 0x0d,而不是 0x0a 或者 0x0d 和 0x0a。这意味着,在 Windows 平台下,回车键对应的字符是 0x0d。 那么,回车符(0x0d)的作用是什么?答案是,回车符...

    上传后缀绕过

    通常情况下,为了防止恶意代码的上传执行,服务器会对上传文件的后缀进行检查和限制。然而,通过一定的技术手段,攻击者可以绕过这些限制,成功上传恶意文件并执行。本文将详细介绍几种常见的上传后缀绕过技巧及其...

    Windows 10系统连接共享打印机报错0x00000709、0x0000007c、0x0000011b.zip

    2. 错误代码0x0000007c:这个错误提示通常与系统组件或驱动程序有关,可能是由于某个必要的系统文件损坏或丢失。 3. 错误代码0x0000011b:这个错误涉及到打印机的端口通信问题,可能是因为打印队列被阻塞或者打印机...

Global site tag (gtag.js) - Google Analytics