1700449115
1700449116
public Sub()throws Exception{
1700449117
1700449118
}
1700449119
1700449120
}
1700449121
1700449122
就这么一段简单的代码,展示了在构造函数中抛出受检异常的三个不利方面:
1700449123
1700449124
导致子类代码膨胀
1700449125
1700449126
在我们的例子中子类的无参构造函数不能省略,原因是父类的无参构造函数抛出了IOException异常,子类的无参构造函数默认调用的是父类的构造函数,所以子类的无参构造也必须抛出IOException或其父类。
1700449127
1700449128
违背了里氏替换原则
1700449129
1700449130
里氏替换原则是说“父类能出现的地方子类就可以出现,而且将父类替换为子类也不会产生任何异常”,那我们回过头来看看Sub类是否可以替换Base类,比如我们的上层代码是这样写的:
1700449131
1700449132
public static void main(String[]args){
1700449133
1700449134
try{
1700449135
1700449136
Base base=new Base();
1700449137
1700449138
}catch(IOException e){
1700449139
1700449140
//异常处理
1700449141
1700449142
}
1700449143
1700449144
}
1700449145
1700449146
然后,我们期望把new Base()替换成new Sub(),而且代码能够正常编译和运行。非常可惜,编译通不过,原因是Sub的构造函数抛出了Exception异常,它比父类的构造函数抛出的异常范围要宽,必须增加新的catch块才能解决。
1700449147
1700449148
可能有读者要问了,为什么Java的构造函数允许子类的构造函数抛出更广泛的异常类呢?这正好与类方法的异常机制相反,类方法的异常是这样要求的:
1700449149
1700449150
//父类
1700449151
1700449152
class Base{
1700449153
1700449154
//父类方法抛出Exception
1700449155
1700449156
public void method()throws Exception{
1700449157
1700449158
}
1700449159
1700449160
}
1700449161
1700449162
//子类
1700449163
1700449164
class Sub extends Base{
[
上一页 ]
[ :1.700449115e+09 ]
[
下一页 ]