`

[#0x0020] 涉及继承的异常声明及捕捉

    博客分类:
  • Java
阅读更多

  当有继承发生时,会伴随着重载、覆写(包括接口方法的实现)、构造器的重写等行为。此时,如果基类或是接口的方法存在异常声明,那么导出类或是接口的实现类的对应方法该如何声明异常?同时对这些方法的调用该如何捕捉异常?下面就这2个问题进行探讨,你会看到,针对覆写和构造器的重写是2种完全不同的处理方式(针对重载则没有任何限制)。代码如下:

//@file	Example1.java

class ExtException extends Exception {}
class AnotherException extends Exception {}

class Base
{
	public void func() {}
	
	public void func2() throws Exception {}
	public void func3() throws ExtException {}
	
	public Base() throws Exception {}
	public Base(int i) throws Exception {}
	//public Base(float f) throws ExtException{} //Error No.5: every other constructor will call the default constructor; same as Error No.4
}

interface Inf
{
	public void func2() throws ExtException;
	//public void func3() throws AnotherException; //Error No.3: base and interface conflicts
	
	public void func4() throws Exception;
	public void func5() throws Exception;
}

class ExtImp extends Base implements Inf
{
	//public void func()  throws ExtException{} //Error No.1: if base function has no exception declaration, overriding CANNOT add one
	
	//public void func2() throws Exception {} //Error No.2: cannot implement interface; base and interface conflicts
	public void func2() throws ExtException {} //implement interface and use Hint No.2
	
	//public void func3() throws ExtException {} //Error No.3
	//public void func3() throws AnotherException {} //Error No.3
	
	public void func4() {} //Hint No.1: if base function has exception declaration, overriding CAN ommit
	public void func5() throws ExtException {} //Hint No.2: if base function has exception declaration, overriding CAN declare ext exception
	
	//public ExtImp() {} //Error No.4: ext's construcor must declare the exception the base constructor declare
	public ExtImp() throws Exception {}	
	//public ExtImp() throws ExtException {} //Error No.4
	
	public ExtImp(int i) throws Exception, ExtException {} //Hint No.3: once ext decalres throwing the base's exception, it CAN declare other exception (不一定非要是父类声明异常的子类), see Example2.java
	
	//public ExtImp(float f) throws ExtException{} //Error No.5
}
//@file	Example2.java

class ExtException extends Exception {}
class AnotherException extends Exception {}
class ThirdException extends Exception {}
class FourthException extends ThirdException {}

class Base
{
	public Base() {}
	public Base(int i) throws ExtException {}
	public Base(float f) throws ExtException {}
	
	public void func() throws ThirdException { System.out.println("Base.func()");}
}

class Ext extends Base
{
	public Ext() throws Exception {}  //Hint No.4: ext's constructor CAN add exception declaration
	public Ext(int i) throws ExtException, AnotherException {} //Hint No.4
	public Ext(float f) throws Exception {} //Hint No.5: ext's constructor can declare base exception
	
	public void func() throws FourthException { System.out.println("Ext.func()");}
}

public class Example2
{
	public static void main(String[] args)
	{
		try
		{
			Ext e = new Ext(5);
			e.func();
		}
		catch (ExtException ee) {}
		catch (AnotherException ae) {}
		catch (FourthException fe) {} // ***DIFFERENCE***
	
		try
		{
			Base b = new Ext(5);
			b.func();
		}
		catch (ExtException ee) {}
		catch (AnotherException ae) {}
		catch (ThirdException te) {} // ***DIFFERENCE***
	}
}

//output:
/*
	Ext.func()
	Ext.func()
*/

 

  针对覆写方法,有以下几点原则:

  1. 如果基类方法没有声明异常,那么导出类的覆写方法也不能声明异常(Error No.1)。

  2. 如果基类方法有声明异常,那么导出类的覆写方法可以:(1)不声明异常;(2)声明抛出基类方法的异常;(3)声明抛出基类方法异常的导出类。(Hint No.1 & Hint No.2)

  3. 如果基类和接口有同签名方法,且导出类实现了接口,如果基类方法和接口方法声明的异常不同,则称基类与接口冲突。如果基类方法抛出的异常和接口方法声明的异常存在继承关系,则实现接口的导出类必须声明抛出导出异常(子异常)(Error No.2);如果如果基类方法声明的异常和接口方法声明的异常不存在继承关系,则冲突不可调和,需要修改基类或是接口(Error No.3)。

  4. 由Example2.java可见,对于向上转型 Base b = new Ext(5),调用b.func()虽然会动态绑定调用Ext的func()方法,可是异常捕捉必须按照Base的func()方法的异常声明来捕捉(见DIFFERENCE处)

 

  针对构造器的重写,有以下几点原则:

  1. 这里应该持这么一种观点,基类的带参构造器和导出类的所有构造器都默认调用了基类的默认构造器,Base(int i)调用了Base(),Ext()调用了super(),Ext(int i)调用了super(i),依次类推。所以一旦基类的默认构造器声明了异常,那么基类的带参构造器和导出类的所有构造器都必须声明异常,异常类型可以是基类默认构造器的异常或是其基类,而决不能是其导出类(Error No.4, Error No.5 & Hint No.5) (与覆写方法抛异常的情况刚好相反)

 

p.s. 导出类构造器虽然不能声明导出异常,不过可以抛出导出异常,如:

class Base
{
	public Base() throws NullPointerException {} 
}

class Ext extends Base 
{
	public Ext() throws Exception
	{
		throw new NullPointerException();
	}
}

所以牢记:声明异常和实际抛出异常完全是两码事

 

  2. 如1.所说,构造器的重写实际是调用关系,所以一旦默认构造器没有声明异常,那么其他构造器就可以随便添加异常声明(Hint No.3 & Hint No.4)。

分享到:
评论

相关推荐

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

    ### 0x000b - 一种异常情况 异常是指程序执行过程中发生的意外事件,可能导致程序崩溃。 ### 0x000c - 获取资源失败 获取资源时出现错误,可能是因为资源已被占用或不存在。 ### 0x000d - 超时 超时错误通常...

    常见蓝屏代码,代码蓝屏

    #### 0x0000000F - 系统服务异常 此错误代码表示系统服务出现异常,可能是由于驱动程序问题或系统文件损坏造成的。 #### 0x00000010 - 注册表错误 如果注册表中的键值或结构损坏,可能导致此错误的发生。 #### 0x...

    windows蓝屏代码

    这可能涉及到文件、目录或其他资源的访问权限。 #### 0x00000006 无效的代码 如果遇到无效的代码,表明系统遇到了不可识别的指令或数据。这可能是由软件编程错误引起的。 #### 0x00000007 储存体控制区块已毁 该...

    Windows 错误码整理

    ### 0x0020 - 文件正在使用中。 如果尝试删除或移动一个正在被其他进程使用的文件,系统会抛出此错误。 ### 0x0021 - 文件共享冲突。 当两个或多个进程试图同时修改同一个文件时,会发生文件共享冲突。 ### 0x0022...

    Windows xp 蓝屏代码详解

    #### 0x0020 - 进程无法访问文件 - **描述**:进程无法访问文件。 - **可能原因**:文件正在被其他进程使用。 #### 0x0021 - 目录条目损坏 - **描述**:目录条目损坏。 - **可能原因**:文件系统错误。 #### 0x...

    电脑蓝屏代码大全

    ##### 0X00005AA、0X00005AB、0X00005AC 系统资源不足,无法完成所要求的服务 当系统资源不足时会出现这些错误。关闭不必要的应用程序和服务,释放系统资源。 #### 结论 电脑蓝屏错误代码是诊断和解决问题的重要...

    windows蓝屏错误代码大全

    与0x00000181类似,但涉及到从处理器电源状态返回时的问题。 #### 0x000001A1 - STATUS_PROCESSOR_POWERSTATE_POLICY 此错误表明处理器电源状态政策出现问题。这通常是由于硬件配置问题或驱动程序错误导致的。 ###...

    TartaricAcid#TXLuaLesson#0X0E中学算术1

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

    蓝屏错误对照表

    - **解决方案**:确认文件路径及名称是否正确,检查文件是否存在并处于可访问的状态。 #### 0x00000003:系统找不到指定的路径。 - **描述**:当系统无法找到指定的文件夹或路径时出现此错误。 - **解决方案**:...

    TaiXuan91#TXLuaLesson#0X2B循环for1

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

    TaiXuan91#TXLuaLesson#0X00目录1

    目录图例Stage1 入门Stage2 基础Stage3 字符串处理Stage4 理解函数Stage5 表结构Stage6 流程控制Stage7 模块Stage

    TaiXuan91#TXLuaLesson#0X36度量时间1

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

    real6410点灯

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

    上传后缀绕过

    ##### 0x01: 前台过滤绕过 通过抓包工具如Burp Suite截取上传请求,将文件名中的`.jpg`修改为`.php`(例如:将`evil.jpg`改为`evil.php`),这样可以绕过前端的文件扩展名检查。由于前端验证通常较为简单,这种方法...

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

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

    windows蓝屏错误代码小解

    ### 0 0x00000000 作业完成 此错误代码表示系统或应用程序成功完成了某项任务。这不是一个错误代码,而是一种状态标识,意味着一切正常运行。 ### 1 0x00000001 不正确的函数 该错误代码表明调用了一个不合适的函数...

    学习笔记stack相关

    每个函数都有其自己的栈帧,并负责创建、保存及恢复调用者栈帧。本章节将详细讨论栈帧的工作机制,以及如何利用缓冲区溢出漏洞来操纵局部变量。 #### 0x340 栈布局 下面通过一个具体的源代码示例来进一步解释栈布局...

    ARM7_test4.rar_keil4怎样编arm程序?

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

    笔记本蓝屏代码.txt

    本文将深入探讨笔记本蓝屏代码的含义、可能的原因以及解决方法,特别关注了几个常见的蓝屏错误代码,包括0x0000000A、0x0000007B、0x000000ED、0x0000007E/0x0000008E、0x00000050和0x000000D1。 #### 0x0000000A:...

Global site tag (gtag.js) - Google Analytics