type
status
date
slug
summary
tags
category
icon
password
异常
在程序运行时,可能出现的不正常情况,称之为异常。如果不处理异常,可能会导致程序的奔溃。手机端的应用程序异常奔溃体现在程序闪退; PC端的应用程序崩溃会终止程序;如果是服务器端的程序,浏览器会提示500
虽然写代码时,会尽可能的让代码更加的完善,但是有一些问题是无法避免,出现这些问题以后,代码应该要停止或者处理问题,例如接收到用户的问题输入后,给一个友好的提示
规避异常: 使用条件判断语句,把出现异常的情况排除。从软件设计层面规避异常,注意规避不是规避异常处理语句。
异常出现以后的处理方式:
- 使用 try...catch语句来处理,用户是看不到异常的
- 使用 throw和throws抛出去,让别人来处理。如果大家都不处理,异常会给到main方法,如果main方法出现了异常,JVM会直接终止程序
Java中的异常分类
- Throwable: 是所有异常的父类
- StackOverFlowError栈溢出错误
- OutOfMemoryError内存溢出错误
- RuntimeException: 运行时异常,可以处理,也可以不处理,这种异常可以规避
- ArithmeticException
- ArrayIndexOutOfBoundsException
- StringIndexOutOfBoundsException
- NumberFormatException
- ClassCastException
- NullPointerException
- 等等
- UnsupportedEncodingException
- ParseException
- IOException
- 等等
Error: 错误,程序运行过程中出现的严重的错误,程序应该终止,不建议程序员解决
Exception:异常,程序员应该解决的问题
非RuntimeException: 编译时异常,必须要使用异常处理语句处理的异常
RuntimeException
- 异常可以不处理,不及时处理这种异常代码依然可以编译通过,但在运行时可能会报错
- 运行时异常可以通过调整代码去规避
运行时异常的处理方式
- 规避,避免出现问题(能够规避的原因:不解决也能编译通过)
- 不解决(大多数写代码时是不解决运行时异常,JDK源码里对于运行时异常都有解决方案)
- 使用 异常处理语句(try...catch、throw、throws) 解决
编译时异常的处理方式
- 编译时异常,必须要使用异常处理语句(try...catch或者throw/throws)解决
- 编译时异常不能调整代码书写逻辑规避,尝试规避后编译依然无法通过!
try...catch
try...catch语句的结构: 如果try代码块里的语句出现异常了,立刻跳转到catch里执行
多个catch之间的异常类型可以有继承关系,但是父类的异常类型一定要写在子类的后面
throw与throws
使用throw在方法体里抛出异常
使用throws在方法声明里声明异常
throw导出是一种自行处理异常手段,而throws是把异常甩给被调用者,没有真正的解决异常
如果在方法体里抛出throw了非运行时异常(编译时异常),在方法声明里就要使用throws声明抛出的异常。反之,如果在在方法体里抛出的是运行时异常,方法声明中就不用关键字throws 声明异常了
异常在继承中的要点
- 父类方法如果抛出了一个异常,子类重写时可以不抛异常。
- 如果子类使用super调用了父类抛出编译时异常的方法,那么子类必须要处理这个异常,要么try...catch,要么抛throw出去(有一些情况只能try...catch不能抛<?> )
- 子类重写方法时不能抛出比父类方法更多的异常,换言之,父类没有抛出的一会,子类也不能抛出
自定义异常
自定义异常的使用: JDK提供了很多的异常类型,如果JDK内置的异常不能够很好的描述当前遇到的问题,就可以考虑自己定义一个异常类型,抛出自己认为可以很好描述清楚问题的异常类型。
自定义异常的注意事项:
- 自定义异常必须要继承自 Throwable 类,通常继承自 Exception 或者 RuntimeException 因为 Throwable有两个子类 Error 和 Exception
- 继承自 Exception 和 RuntimeException 的区别在于:如果是继承自 Exception,方法声明里一定要使用 throws声明抛出的异常
Scanner抛出异常
finally
无论程序是否出现异常,在程序正常或者异常终止之前,都会先执行一次finally代码块里的内容。但是在程序出现问题之前直接就退了的话,finnally代码块里语句就不会执行。比方说在try语句的异常代码块之前或者catch代码块里如果有System.exit()的时候,就满足这种情况
如果程序没有异常,或者出现的异常在catch里解决了, 先执行finnally代码块看 的的内容,然后调用System.exit(0)
如果程序出错了没有解决,先执行finnally代码块的内容,然后调用System.exit(1)
如果finnally里面也抛出了异常,finnally里的异常会覆盖try...catch里的异常
如果finnaly里有return语句,他会覆盖之前的return语句
- try...catch..finally
- try...finally
- 作者:tacjin
- 链接:http://jin.wiki/article/f9563b7d-4fd7-41a7-9eb5-66d0516ede1b
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。