之前本帅博主写过一篇关于try-catch和finally的文章,即try-catch与finally语句块中使用return的注意事项以及相关引申,这篇文章讲述了一些它们之间的注意事项。
这try-catch语句块中,还有很重要的一点,就是异常。
对于异常,我们从来都不陌生。可以说,自从我们第一次写代码到现在的第n次写代码,异常从未离我们远去,甚至随着我们学习面的逐渐旷阔而变得越发的频繁与复杂。
程序中抛出异常呢,其实有三种方式。一种就是我们最初的时候就开始遇见的,也就是最常出现的,由系统抛出异常。
所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常 |
什么时候系统会自动抛出异常呢?
当程序语句出现一些逻辑错误、主义错误或类型转换错误时,系统会自动抛出异常。 |
举个栗子:
public static void main(String[] args) {
int a = 5, b =0;
System.out.println(5/b);
}
系统会自动抛出ArithmeticException异常,如图:
或者
public static void main(String[] args) {
String s = "abc";
System.out.println(Double.parseDouble(s));
}
系统会自动抛出NumberFormatException异常,如图:
上面看了一些系统自动抛出异常的例子,不过这个不是咱们今天的主菜。咱们今天呢,主要看看我们另外两种抛出异常的方式,即throw和throws,用户程序自定义的异常和应用程序特定的异常,就必须借助这两种方式来定义抛出异常。
1.throw
throw是语句抛出一个异常。
语法:
throw (异常对象);
如 throw e;
throw抛出异常不一定是真的出错了,只要符合条件,你就可以抛出异常。
举个例子:
public class test {
public static void main(String[] args) {
String s = "Searchin";
if(s.equals("Searchin")) {
throw new NumberFormatException();
} else {
System.out.println(s);
}
}
}
运行结果如下:
2.throws
throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常(抛出的是一个异常类对象,这个对象带有所发生异常的信息))
语法:
[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{......}
public void doA(int a) throws Exception1,Exception3{......}
我们可以使用已有的异常类,也可以自己定义一个异常类。如果我们需要抛出一个具体的异常信息可以用JAVA中已有的异常类构造一个新的异常类对象,把相应的异常信息传给它就可以了。比如:
public class Test {
public void A() throws IOException{
int i=0;
if(i==0) {
throw new IOException("i不能等于0,请换一个数字");
}
}
//主函数入口
public static void main(String[] args) throws IOException {
Test t=new Test();
t.A();
}
}
程序运行结果如下:
可以看到这里,我们就将IO异常输出了。那自定义的异常都会这样输出嘛?
我们将上面的程序改一下:
public class Test {
public void A() throws IOException{
int i=0;
if(i==0) {
throw new IOException("i不能等于0,请换一个数字");
}
}
//主函数入口
public static void main(String[] args) {
Test t=new Test();
try {
t.A();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("这个方法出错啦");
}
}
}
运行结果如下:
通过这两个程序,我们可以知道,在第一个程序中我们没有对异常进行处理,因此需要给main方法加上throws IOException,将异常提交给上级来处理。它的上一级是谁呢?那当然是JVM啦。A方法的上一级是main函数,main函数的上一级也就是JVM,如果main函数不处理异常,那么JVM会处理异常。JAVA虚拟机根据IOException所带的异常信息,判断这是自定义的异常,于是终止程序,并且打印出报错信息。
而在第二个程序中,因为在main函数捕捉到异常并进行了处理(即输出“这个方法出错啦”),因此就不需要靠上一级来解决问题啦。
如果想要知道异常的内容,只需要借助printStackTrace()即可。即
程序运行结果如图:
3.throw与throws的异同
throw与throws的区别:
- throws出现在方法函数头;而throw出现在函数体。
- throws表示出现异常的一种可能性,即主要是声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常。但是并不一定会发生这些异常;throw则具体向外抛异常的动作,执行throw则一定抛出了某种异常(异常实例)。
throw与throws的共同点:
- 两者都不会由函数去处理异常。它们只是抛出或者可能抛出异常,真正的处理异常由函数的上层调用处理。
4.总结
异常是会一层层往上抛的,直到遇到了某个方法处理了这个异常或者最后抛给了JVM。但是如果都把异常让JVM去处理,这并不是一个好的习惯,因为JVM对异常的处理比较宽泛的,它无法具体到一些细节的问题上。所以我们最好我们自己定义一个catch去处理这个异常。至于怎么处理异常,大家可以参照try-catch与finally语句块中使用return的注意事项以及相关引申(这篇博客有提及相关知识)。此外,书上和网上都有很多具体的例子,大家可以参照一些网上提供的例子。
好啦,以上就是关于throw与throws异同的相关知识总结啦,如果大家有什么不明白的地方或者发现文中有描述不好的地方,欢迎大家留言评论,我们一起学习呀。
Biu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~pia!
注:如果想要了解Java中都有哪些异常,可以参考:java中都有哪些异常