一、异常
异常是指程序在运行过程产生的不正常情况。语法错误不算异常。
1、异常体系
Throwable:Java语言中所有错误或异常的超类;Throwable 类的子类有两个:1、Error;2、Exception。
1、所有的异常类都是 java.lang.Exception 的子类,Exception相对来说,可以控制,可以处理。
2、Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。例如:JVM 内存溢出。
3、Error 用来指示运行时环境发生的错误。
4、通过看子类是Exception结尾还是Error结尾,来判断是Exception体系还是Error体系。
异常分类
运行时异常:RuntimeException 以及它子类的类型。
如果没有处理(抛出或者try-catch),编译不会报错。
非运行时异常:Exception 以及它的子类,但是除去RuntimeException和它的子类。
如果没有处理(抛出或者try-catch),编译的时候报错。
2、异常处理
异常处理有两种方式:
1、自己处理try -catch
写在可能发生异常代码的地方,如果出现异常,产生异常,就会被捕捉到,捕捉的异常信息放到异常类型的变量里面去;这样就可以进行处理这个异常。
如果没有异常出现,就不捕捉,就往下面继续执行走。
语法结构:
try{ //可能出现异常 }catch(异常类型 变量名){ //处理异常代码}
处理异常代码:
1、把错误提示给用户。直接调用 printStackTract方法就打印异常信息。
2、把异常信息,保存到日志文件,便于查看。
2、自己不处理,向外抛出
抛出到JVM,还可能在实际开发过程,遇到方法调用方法,调用很多层,那种抛出,就像上一层调用者进行抛出。
throws 和 throw的区别:
throws 表示向外抛出异常,位置:方法的(){}之间,特点:后面跟多个异常。
throw 产生一个异常对象,位置:方法里面。特点: 后面跟一个异常对象,相等于return的效果。
1 public class ThrowsDemo { 2 /** 3 * 计算两个整数相除 4 * @param a 5 * @param b 6 * @throws Exception 7 */ 8 public void div(int a, int b) throws Exception { // 抛出异常 9 System.out.println(a / b);10 }11 12 /**13 * 测试div14 */15 @Test16 public void testDiv() throws Exception {17 div(1, 0); //打印异常:java.lang.ArithmeticException: / by zero18 }19 }
3、多异常处理
语句结构:
1 try{2 //可能出现异常的代码。。。3 }catch(异常类型 变量名){4 // 处理异常的代码5 }catch(异常类型 变量名){6 // 处理异常的代码7 }catch(异常类型 变量名){8 // 处理异常的代码9 }
3、异常finally语句
除了上面两种扑捉异常结构以外,还有其他的结构,可以在最后面添加一个finally
语法结构:
try{ //可能出现异常的代码 }catch(异常类型 e){ //处理异常: //1 打印到控制台 //2 保存到文件 //3 还可能向外抛出新的异常 }finally{ }
finally单词什么含义,表示最终的意思。
1、关闭流资源或者释放锁--线程。
2、如果在finally前面没有执行系统退出(system.exit(0))的语句,此处的代码始终都会执行。
3、不要在此处放return语句来返回一个数据。
1 public class ExceptionTest { 2 /** 3 * 测试出现异常时,程序的执行顺序 4 */ 5 @Test 6 public void test1(){ 7 try { 8 System.out.println("------执行1------"); 9 System.out.println("------执行2------");10 System.out.println("------num------" + (1/0)); //出现异常之后,不执行后面代码,即不打印------执行3------11 System.out.println("------执行3------");12 } catch ( ArithmeticException e) {13 System.out.println("------catch1------");14 System.out.println("------catch2------");15 e.printStackTrace(); //打印异常信息 java.lang.ArithmeticException: / by zero16 System.out.println("------catch3------");17 } finally { //不管是否有异常都要执行18 System.out.println("------finally1------");19 System.out.println("------finally2------");20 System.out.println("------finally3------");21 }22 }23 }
4、自定义异常
创建了一个异常类,需要模拟产生自定义异常的场景:
1、自定义一个异常类型,需要创建一个类继承Exception或者RuntimeException,覆写里面的两个构造方法。
2、模拟一种场景,创建一种自定义异常的对象,通过throw创建异常对象。
3、使用上面场景,抛出或者处理
1、自定义一个异常类型。
1 /** 2 * 自己定义异常对象 3 */ 4 public class LoginUserException extends RuntimeException{ 5 public LoginUserException() { //覆写构造方法 6 super(); 7 } 8 9 public LoginUserException(String message) { //覆写构造方法10 super(message);11 }12 }
2、使用throw产生异常对象LoginUserException。
1 public class LoginUserTest { 2 public String checkLogin(String username, String password){ 3 if (!(Objects.equals(username, "user"))){ 4 System.out.println("------执行1------"); 5 System.out.println("------执行2------"); 6 System.out.println("------执行3------"); 7 throw new LoginUserException("name is wrong"); //自定义异常信息,throw的用法,产生一个异常对象LoginUserException 8 } 9 return "返回结果";10 }11 12 }
3、测试异常:
1 public class ExceptionTest { 2 /** 3 * 测试自定义异常 4 */ 5 @Test 6 public void testCheckLogin(){ 7 LoginUserTest loginUserTest = new LoginUserTest(); 8 String s = loginUserTest.checkLogin("user1", ""); 9 System.out.println("----s:" + s); //打印异常:exception.LoginUserException: name is wrong10 }11 }