杂谈——运行时异常和普通异常有什么区别

说到异常,大家都熟悉,只要程序出错了,那么肯定会说:“哎呀,我的程序出错啦~它抛出异常啦”。

但单单以“异常”的名称来称呼它们,未免也太粗糙了。我们毕竟是一个精致的程序员,当然得知道他们到底都有哪些种类啦。这就好比一个优质的男朋友(比如本帅博主)必须能够精准地区分女朋友的口红色号一般。

那Java到底有哪些异常呢?

其实也不多,Java提供了两种错误的异常类,分别是Error和Exception,它们的爸爸(即父类)都是Throwable,从这个角度来看,它们也算的上是亲兄弟啦。

但哪怕是兄弟,那也会有差别。那么咱们就来看看这两兄弟都有区别。

1.Error

Error,看名字就知道,这个错误肯定不会小,事实上也的确是如此,Error表示程序在运行期间出现了非常严重的错误,并且该错误是不可恢复的。

这个错误到底有多严重呢?“Error属于JVM层次的错误”。

JVM我们都知道,代码的顺利运行时离不开JVM这位大佬的。当JVM层次出现错误,那铁定会导致程序终止运行。此外,编译器不会检查Error是否被处理了,所以呀,在程序中我们不推荐去捕获Error类型的异常,主要的原因就是运行时异常大多都是逻辑错误导致的,它属于应该解决的错误,也就是说,一个正常的程序中是不应该存在Error的。像我们平常经常遇见的OutOfMemoryError、ThreadDeath等都是属于Error的,当这些错误发生的时候,JVM基本上都会选择让程序终止。

怎么理解上面的话呢,举个例子。假如咱们在面试的时候,和面试官爆发了语言上乃至身体上的冲突,这种错误就是Error,出现这种错误,面试铁定得中断了呀,毫无疑问的,咱们这次面试肯定也就凉凉了。对方不需要知道你在这件事情发生之后有没有进行反省或者挽救,反正你这回面试就是凉了,再怎么补救都没有用。我们只能放弃这次面试,改过自新,争取在下一次面试的时候不再出现这样的Error,这样才有可能让面试顺利进行,而不被中断。

所以呀,无论是写代码还是做别的事情,咱们都得谨慎,因为一旦出现了Error,无论咱们怎么补救,对本次程序运行或者事情都是无济于事的。

2.Exception

上面说到Error是一个超级重大的错误,那么作为它的兄弟,或多或少在这一方面会对Error的强硬有一些弥补。

Exception表示的是可恢复的异常,是编译器可以捕捉到的,而这家伙有包含这两种类型:检查异常恶化运行时异常。

(1)检查异常

检查异常是在程序中最经常碰到异常,所有继承自Exception并且不是运行时异常的异常都是检查异常,比如咱们最常见的IO异常和SQL异常。这种异常都发生在编译的阶段,Java编译器强制程序去捕获此类型的异常,即它会把可能会出现这些异常的代码放到try块中,把对异常的处理代码放到catch块中。这种异常一般在如下几种情况中使用:

  • 异常的发生并不会导致程序出错,进行处理之后可以继续执行后续的操作,比如,连接数据库失败之后可以重新连接之后再进行后续操作。
  • 程序依赖于不可靠的外部条件,比如系统IO。

(2)运行时异常

运行时异常不同于检查异常,编译器没有强制对其进行捕获并处理,如果不对异常进行处理,那么当出现这种异常的时候,会由JVM来处理,比如NullPointerException异常,它就是运行时异常。

在Java语言中,最常见的运行时异常包括NUllPointerException(空指针异常)、ClassCastException(类型转换异常)、ArrayIndexOutOfBoundsException(数组越界异常)、ArrayStoreException(数组存储异常)、BufferOverflowException(缓冲区溢出异常)、ArithmeticException(算术异常)等。

出现运行时异常之后,系统一般会把异常一直往上层抛,知道遇到处理代码位置,如果没有处理代码,那就一直抛到最上层;如果是多线程就会用Thread.run()的方法抛出;如果是单线程就用main()方法抛出。抛出之后呢,如果是线程,那么这个线程也就退出了,如果是主程序抛出的异常,那么这个主程序也就退出了。所以说,如果不对运行时的异常进行处理,后果也是非常严重的,一旦发生这种异常,要么是线程中止,要么就是主程序终止。

不过,在进行异常处理的时候,还需要注意一下几个问题:

(2.1)Java异常处理用到了多态的概念,如果在异常处理过程中,先捕获到了基类,然后再捕获子类,那么捕获子类的代码永远都不会被执行。因此,在进行以后才那个捕获的时候,正确的方法是先捕获子类,然后再捕获基类的异常信息。

错误示例如下:

try{
    //access db code
}catch(Exception e2)
{
    //deal with this exception
}catch(SQLException e1)

那要怎么写呢,如下: 

try{
    //access db code
}catch(SQLException e1)
{
    //deal with this exception
}catch(Exception e2)

(2.2)我们要尽早地抛出异常,同时对捕获的异常进行处理,或者从错误中恢复,或者让程序继续执行。咱们程序员得时刻记住,对捕获的异常不进行处理是一个非常不好的一贯,这样将非常不利于调试。但是,也不是抛出的异常越多越好,对于有些异常,比如运行时异常,实际上根本不必处理。

(2.3)可以根据实际的需求自定义一场类,这些自定义的一场类只要是继承自Exception类即可。

(2.4)异常能处理就处理,不能处理就抛出,对于一般异常来说,如果不能进行有效的处理,最好转换成为运行时异常抛出。而对于最终没有被处理的异常,JVM会进行处理。

关于检查异常和运行时异常,我们来看一个例子:

public class ExceptionTypeTest {
	public void doSomething()throws ArithmeticException
	{
		System.out.println("this is doSomething");
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExceptionTypeTest ett=new ExceptionTypeTest();
		ett.doSomething();
	}
}

大家猜猜,这段程序可以编译通过吗?

我们来试一试。

上图表示这是可以的。那么,如果咱们更换一下异常的种类,将ArithmeticException换成IOException异常呢?

可以看到代码会提示错误。如果强行执行的话,将报错,如下图。

为什么ArithmeticException可以编译通过,而IOException不可以呢?因为前者属于运行时异常,编译器没有强制对其进行捕获并处理,因此编译可以通过。而IOException属于检查异常,编译器会强制去捕获此类型的异常,如果不对异常进行捕获的话将会有编译错误。

因此,我们只要捕获一下异常就可以了 用try-catch或者throws即可。如下图:

方法一:

方法二:

运行结果如下:

3.总结

 Error:是JVM(java虚拟机)中出现的不可恢复的错误。
 Exception:是类发生的异常,又具体分为以下三种:

  •    检查异常:  编译期发生
  •    运行时异常: 运行期(运行时)发生
  •    自定义异常

总而言之,对于异常,需谨慎,切记哟~。

好啦,以上就是关于运行时异常和普通异常的相关知识总结啦,如果大家有什么不明白的地方或者发现文中有描述不好的地方,欢迎大家留言评论,我们一起学习呀。

 

Biu~~~~~~~~~~~~~~~~~~~~宫å´éªé¾ç«è¡¨æå|é¾ç«gifå¾è¡¨æåä¸è½½å¾ç~~~~~~~~~~~~~~~~~~~~~~pia!

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值