当有继承发生时,会伴随着重载、覆写(包括接口方法的实现)、构造器的重写等行为。此时,如果基类或是接口的方法存在异常声明,那么导出类或是接口的实现类的对应方法该如何声明异常?同时对这些方法的调用该如何捕捉异常?下面就这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...
这可能涉及到文件、目录或其他资源的访问权限。 #### 0x00000006 无效的代码 如果遇到无效的代码,表明系统遇到了不可识别的指令或数据。这可能是由软件编程错误引起的。 #### 0x00000007 储存体控制区块已毁 该...
### 0x0020 - 文件正在使用中。 如果尝试删除或移动一个正在被其他进程使用的文件,系统会抛出此错误。 ### 0x0021 - 文件共享冲突。 当两个或多个进程试图同时修改同一个文件时,会发生文件共享冲突。 ### 0x0022...
#### 0x0020 - 进程无法访问文件 - **描述**:进程无法访问文件。 - **可能原因**:文件正在被其他进程使用。 #### 0x0021 - 目录条目损坏 - **描述**:目录条目损坏。 - **可能原因**:文件系统错误。 #### 0x...
##### 0X00005AA、0X00005AB、0X00005AC 系统资源不足,无法完成所要求的服务 当系统资源不足时会出现这些错误。关闭不必要的应用程序和服务,释放系统资源。 #### 结论 电脑蓝屏错误代码是诊断和解决问题的重要...
与0x00000181类似,但涉及到从处理器电源状态返回时的问题。 #### 0x000001A1 - STATUS_PROCESSOR_POWERSTATE_POLICY 此错误表明处理器电源状态政策出现问题。这通常是由于硬件配置问题或驱动程序错误导致的。 ###...
0X0E中学算术前置知识0X0D数学库函数正文有了三角函数、反三角函数、对数函数、求幂运算,中学阶段涉及的所有具体的数值计算基本就都可以求解。求此表达式的值:第
- **解决方案**:确认文件路径及名称是否正确,检查文件是否存在并处于可访问的状态。 #### 0x00000003:系统找不到指定的路径。 - **描述**:当系统无法找到指定的文件夹或路径时出现此错误。 - **解决方案**:...
0X2B循环for前置知识0X29再谈循环正文Lua除了while和repeat语句还提供了一种for循环语句.while和repeat语句循环终止条件可以是任
目录图例Stage1 入门Stage2 基础Stage3 字符串处理Stage4 理解函数Stage5 表结构Stage6 流程控制Stage7 模块Stage
1. 度量脚本执行时间 2. 记录时间 3. 计算时间间隔
安全运营相关文章本篇整理一些安全运营相关的高质量文章[2] 体系化的WAF安全运营实践, 安全研究与实践,
根据提供的信息,我们可以了解到这是一段与 real6410 开发板相关的代码,主要涉及了点亮 LED(点灯)的操作。此操作是在 U-Boot(一个常用的嵌入式设备启动加载程序)环境下进行的。下面我们将从以下几个方面对这段...
##### 0x01: 前台过滤绕过 通过抓包工具如Burp Suite截取上传请求,将文件名中的`.jpg`修改为`.php`(例如:将`evil.jpg`改为`evil.php`),这样可以绕过前端的文件扩展名检查。由于前端验证通常较为简单,这种方法...
### 0x01 "经典的"Shift后门 这是一种较老但仍然有效的隐藏方式。在早期Windows版本中,攻击者可以将`setch.exe`替换为自己的后门程序,用户在登录界面连续按五次Shift键时,原本应显示粘滞键的CMD窗口反而会运行...
- **0x000a**: 内核模式下的异常情况。 #### 0x000b - 0x0010 - **0x000b**: 一个设备驱动程序尝试执行不支持的操作。 - **0x000c**: 无法成功获取指定资源。 - **0x000d**: 设备驱动程序或服务存在严重错误。 - *...
### 0 0x00000000 作业完成 此错误代码表示系统或应用程序成功完成了某项任务。这不是一个错误代码,而是一种状态标识,意味着一切正常运行。 ### 1 0x00000001 不正确的函数 该错误代码表明调用了一个不合适的函数...
# 0X3 基于VMM的syscallHook ## 0x3-1 Hook思路 拦截C0000082的读写调用 读则返回原先的值,写则禁止写入,实际上通过修改MSR的LSTAR,来进行syscallHook; 从而达到,外部读MSR的SyscallRip没有问题,但是实际syscall调用...