Java Exception - 使用throws声明抛出异常
使用throws声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用throws声明抛出异常,该异常将交给JVM处理。JVM对异常的处理方法是,打印异常的跟踪栈信息,并中止程序运行。
throws声明抛出只能在方法签名中使用,throws可以声明抛出多个异常类,多个异常类之间以逗号隔开。一旦使用throws语句声明抛出该异常,程序就无须使用try…catch块来捕获该异常了。
@Slf4j
public class ExceptionTest {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream("a.txt");
}
}
上面程序声明不处理IOException异常,将该异常交给JVM处理,所以程序一旦遇到该异常,JVM就会打印该异常的跟踪栈信息,并结束程序。
如果某段代码中调用了一个带throws声明的方法,该方法声明抛出了Checked异常,则表明该方法希望它的调用者来处理该异常。也就是说,调用该方法时要么放在try块中显式捕获该异常,要么放在另一个带throws声明抛出的方法中。
FileInputStream的构造方法 :
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
@Slf4j
public class ExceptionTest {
public static void main(String[] args) throws FileNotFoundException {
// 因为test()方法抛出了FileNotFoundException异常
// 所以调用test()方法的代码要么位于try...catch块中
// 要么处于另一个待throws声明抛出的方法中
test();
}
private static void test() throws FileNotFoundException {
// 因为FileInputStream的构造方法抛出了FileNotFoundException异常,即编译时异常
// 所以调用FileInputStream构造方法的代码要么位于try...catch块中
// 要么处于另一个待throws声明抛出的方法中
FileInputStream fileInputStream = new FileInputStream("a.txt");
}
}
使用throws声明抛出异常时有一个限制,就是方法重写时“两小”中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。
@Slf4j
public class ExceptionTest {
public void test() throws FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream("a.txt");
}
}
public class SubClass extends ExceptionTest {
@Override
public void test() throws Exception {
super.test();
}
}
SubClass子类中的test()方法声明抛出Exception,该Exception是其父类声明抛出异常FileNotFoundException类的父类,这将导致程序无法通过编译。
由此可见,使用Checked异常至少存在如下两大不便之处:
- 对于程序中的Checked异常,Java要求必须显式捕获并处理该异常,或者显式声明抛出该异常。这样就增加了编程复杂度。
- 如果在方法中显式声明抛出Checked异常,将会导致方法签名与异常耦合,如果该方法是重写父类的方法,则该方法抛出的异常还会受到被重写方法所抛出异常的限制。
在大部分情况下,推荐使用Runtime异常,而不使用Checked异常。尤其当程序需要自行抛出异常时,使用Runtime异常将更加简洁。
当使用Runtime异常时,程序无须在方法中声明抛出Checked异常,一旦发生了自定义错误,程序只管抛出Runtime异常即可。如果程序需要在合适的地方捕获异常并对异常进行处理,则一样可以使用try…catch块来捕获Runtime异常。
2201_75986890: 是参考观测站(主站)
CSDN-Ada助手: 推荐 Java 技能树:https://edu.csdn.net/skill/java?utm_source=AI_act_java
艾思科蓝 AiScholar: 您好,有兴趣谈一下推广宣传合作吗~方便的话私信我~
z885766: 时间吧
普通网友: 干货满满,实用性强,博主的写作风格简洁明了,让人一目了然。文章涵盖了很多实用的知识点。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】