1.异常
a:什么是异常?
异常是程序编译或者运行时的一种不正常的状态,但是这种不正常的状态不一定会出现
b:异常对程序有什么影响?
程序的稳定性安全性降低,程序会挂起
c:为什么要使用异常?
增加程序的稳定性安全性,至少要让程序能正常结束
d:异常和错误是不是一个概念?
错误是无法处理的,除非把程序逻辑修改正确
异常是可以处理,修改程序逻辑或者使用异常处理机制
2.异常类:java会报大部分经常出现的异常用一个类来描述,一点系统出现了异常就表示一定会有或者需要有一个异常类的对象来对应
3.常见的异常类:
ArithmeticException(除0异常)
ArrayIndexOutOfBoundsException(数组下标越界异常)
ClassNotFoundException(没有发现类异常)
NullPointerException(空指针异常)
NumberFormatException(数据格式化异常)
4.异常类的层次结构:
Object
-->Throwable
-->Error-->XXError(错误类以及错误类的子类)
-->Exception(异常)
-->非RunnTimeException(非运行时异常,在编译的时候就会有提示,必须要用一场处理机制处理,但是处理完毕后运行的时候不能保证没有问题出现)
-->ClassNotFoundException、SQLException
-->RunnTimeException(运行时异常,在编译的时候就不会有提示,可以不用异常处理机制处理,但是运行的时候不能保证没有问题出现)
-->ArithmeticException、ArrayIndexOutOfBoundsException、NullPointerException、NumberFormatException
5.异常堆栈信息的分析:
首先读第一行,告诉我们是什么错误
从第一行向下找第一次出现的自己的类名的位置,点击后方的链接,会跳转到异常出现的具体位置
接下来,可以使用异常处理机制处理
6.异常处理机制(try-catch-finally throws throw)
try{}:把可能出现异常的代码放在在其中
catch(异常引用){}:尝试去捕获try中出现的异常,如果捕获成功,那么程序会从try块直接跳入catch块执行;如果没有捕获成功,程序按照既定流程执行
finally{}:不管程序中有没有异常都必须执行的代码块
问题:在try-catch中有return会不会影响finally{}里内容的执行? -----不会
如果一段程序出现多个异常,尽量避免出现try-catch嵌套
for (int i = 0; i < array.length; i++) {
try {
try {
System.out.println(array[i+1] / array[i] );
}catch(ArithmeticException e) {
System.out.println("除数不能为0");
}
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("数组下标越界");
}
}
原则:
(1)如果有for,if等结构体,那么try-catch应该在这个结构体的外部
(2)嵌套try-catch尽量的修改成多重try-catch
try {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i+1] / array[i] );
}
}catch(ArithmeticException e) {
System.out.println("除数不能为0");
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("数组下标越界");
}catch(Exception e) {
System.out.println("程序有异常");
}
System.out.println("程序继续");
(注意:多重catch捕获的时候,捕获的异常类的引用,从小往大来编写)
问题:
try-catch可以搭配使用,try-finally能不能搭配使用,catch-finally能不能搭配使用?
try-finally可以搭配使用,catch-finally不能搭配使用
7.throws:抛出异常(可以抛出多个异常)
在程序出现异常的位置,不对异常继续处理,但是又想让当前这块程序能执行,那么可以把当前位置出现的异常从当前的方法中抛出;或者提供一种思路
throws的位置:方法的结尾
public void method() throws 异常列表
注意:当一场从某个方法中抛出以后,那个方法调用了这个抛出异常的方法,那么异常就引入到哪个方法中去了;而且抛出是可以多层抛出;在层次结构的抛出中抛出的的异常可以越来越抽象
8.throw 自定义异常
系统异常无法满足要求的时候,可以定义新的异常,这个异常要按照异常的层次结构来定义
步骤:
(1)自定义异常类:
public class LoginFailException extends Exception {
public LoginFailException(String message) {
super(message);
}
}
(2)在合适位置生成异常类对象:
public class UserDAOImpl implements UserDAO{
@Override
public void findByUnameAndPwd(String uname, String upwd) throws LoginFailException {
// TODO Auto-generated method stub
if ("admin".equals(uname)&&"123123".equals(upwd)) {
}else {
//生成自定义异常
throw new LoginFailException("登陆失败,用户名或者密码错误!");
}
}
}
(3)在合适的位置处理异常:
public static void main(String[] args) {
UserDAO userDAO = new UserDAOImpl();
try {
userDAO.findByUnameAndPwd("admin", "123123");
System.out.println("登陆成功");
} catch (LoginFailException e) {
System.out.println(e.getMessage());
}
}