今日内容
-
异常
异常:
异常的根类是java. lang . Throwable,其下有两个子类分别是:java . lang .Error 和 java . lang. Exception.
Error是错误,不可通过异常处理的错误,就好比人体的艾滋病,癌症等,只能是事先预防
今天主要是说Exception(编译期异常):异常。是可以通过代码的方式进行修改纠正,然后可以继续进行下去。好比人的感冒等
Exception的RuntimeException(运行期异常)包括常见的:
ArrayIndexOutOfBoundsException: 索引越界异常
其中有5个关键字:throw , throws , try catch , finally
throw:抛出异常
编写程序的时候程序可能会出现问题,可以使用throw关键字在指定的方法中抛出指定的异常
使用格式:
throw new XxxException("异常产生的原因");
注意:
1.throw关键字写在方法的内部。
2.throw关键字后面必须是Exception或者Exception的子类对象
3.throw关键字抛出指定的异常对象后。我们就必须去处理这个异常对
throw关键字后面创建的是RuntimeException或者RuntimeException的子类对象,我们可以选择不处理,交给(打印异常对象,)
throw关键字后面创建的是编译异常(写代码的时候就会出现的问题),我们就必须处理这个异常,要么是throws,要么使用try。。。catch
public static void main(String[] args) { int[] arr = null; int a = get(arr, 2); System.out.println(a);// } public static int get(int[] arr,int index){ if (arr==null) { // throw new NullPointerException("传递的数组值为null"); } return arr[index]; } }
throws关键字
异常处理的第一种方式:声明异常处理,将异常交给方法的调用者来处理
当方法内部抛出了异常,我们必须处理这个异常对象,这个方法把异常对象抛给方法的调用者,调用者再网上抛,最终教给虚拟机,虚拟机中断处理
格式:
修饰符 返回值类型 方法名(参数列表) throws XxxException,ZzzException...{ throw new XxxException("产生的原因"); throw new ZzzException("产生的原因"); ...... }
注意:
1.throws 关键字必须写在方法声明处。
2.throws 关健字后面声明的异常必须是Exception或者是Exception的子类
3.方法内部如果抛出了多个异常对象,那么throws后面也必须声明对应的多个异常,如果抛出的多个异常对象有父子类关系的时候,可以直接声明父类类型即可
4.调用了一个声明抛出异常的方法(通过throw方法抛出),我们就必须处理这个异常声明,要么继续throws抛出,要么使用try...catch处理
备注:异常到哪一个,就终止在哪。
public static void main(String[] args) throws FileNotFoundException, TimeoutException { String pString ="C:\\abc.txt" ; haha(pString); System.out.println( "keyi "); } public static void haha(String pString) throws FileNotFoundException, TimeoutException{ if (!pString.endsWith("txt")) { throw new FileNotFoundException("不是txt"); } if (!pString.startsWith("C:")) { throw new TimeoutException("不是C盘"); } }
Objects非空判断
该类中提供了静态方法,null - save(空指针安全)或者null- tolerant(容忍空指针)。在他的源码中,对对象的null值进行了抛出异常的操作
public static <T> T requireNonNull(T obj){ if(obj == null) throw new NullPointerException(); return obj; }
捕获异常try...catch
自己处理异常
如果异常出现的话,会立即终止程序。两种方法
1.上述throws声明处理,危险
2.方法中使用try...catch的语句块来处理异常
try .... catch的方式是捕获异常
捕获异常的方式:可以对出现的异常指定方式捕获;
格式:
try{ //编写的可能会出现异常的代码 //..... }catch(异常类型 c){ //处理异常的逻辑代码 //一般在工作中,会把异常的信息记录到日志中 }
其中try:该语句块中可能出现异常的代码
catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理
备注:try和catch都不能单独使用,一般建议连用
演示:
Thowable类中定义了一些常用的api方法
public String getMessage()获取异常的描述信息,原因(提示给用户看的,提示错误原因);
public String toString();获取异常的类型,异常的描述信息
public void printStackTrace(): 打印异常的跟踪栈信息并输出到控制台中
这包含了异常的类型,原因,出现的位置。开发和调试阶段一般都适用
Finally语句块
finally: 有一些特殊代码无论异常是否发生,都需要执行,当程序发生异常时,会引发程序的跳跃性,finally语句块中的代码是一定会被执行到的。
格式:
try{ // }catch(异常类型 e){ //... } ... }finally{ //... }
备注:中间的catch语句块可以不省略,finally不能单独使用,建议连用
注意事项:
1.finally不能单独使用,必须和try一起使用
2.finally语句块一般用于资源的释放,(资源回收),无论程序是否出现异常,最后都要加载finally语句块中的内容,都要释放资源
备注:
如果finally语句块中有return语句,永远返回的是finally语句块中的结果值。
当只要在try或者catch中调用退出JVM的相关方法,此时finally才不会被执行到,否则finally永远会执行
异常的注意事项
程序中出现多个异常
1.多个异常分别处理
2. 多个异常一次捕获,多次处理
3.多个异常一次捕获,一次处理
一般用的是一次捕获,多次处理,格式如下:
try{ //可能出现异常的代码 多个异常 }catch(异常A){//当try中出现A异常的时候,就用该catch来捕获 //处理异常的逻辑 }catch(异常B){//当try中出现B异常的时候,就用该catch来捕获 //处理异常的逻辑 } .... ...
要求catch多个异常不能相同,异常之间有父子关系,子类处理在上,父类在下。
- 运行时异常被抛出可以不处理,即不捕获也不声明抛出
- 如果finally中有return语句,那么永远返回finally语句块中的结果值
- 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
- 父类方法如果没有抛出异常,子类重写该方法时,也不可能抛出。此时如果子类方法内产生了异常,只能捕获处理,不能声明抛出。
自定义异常
概述:
出去官方提供的异常外,还要自定义的异常类。例如:年龄负数,成绩负数,登录异常等等
异常类定义:
- 自定义一个编译期异常,自定义类继承于java.lang.Exception。
- 自定义一个运行期异常类,自定义类继承与java.lang.RuntimeException。
例子:
//自定义异常类步骤 //1.定义一个异常类 类继承系统给定的异常类 public class ExceptionDemo01 extends Exception { // 空参构造 public ExceptionDemo01() { } // 全参 参数设置为传输的字符串 public ExceptionDemo01(String a) { super(a); } } public class Application { // 成员静态变量设置 public static String[] name = { "小孙", "小王", "小丽", "小张" }; public static void main(String[] args) { Scanner sc = new Scanner(System.in); String names = sc.next(); // 3.try...catch try { // 方法调用,有参数的话要传参数 nemeDemo(names); System.out.println("名字可以,万里挑一"); // ()里面是异常类名 e是给方法生成名字 } catch (ExceptionDemo01 e) { // 调用输出方法三种 e.printStackTrace();// 直接打印异常所有信息 System.out.println(e.getMessage());// 显示内容及类型 System.out.println(e.toString());// 只显示内容 } } // 2.做一个方法遍历检查 public static void nemeDemo(String uname) throws ExceptionDemo01 { // for遍历 for (String string : name) { if (string.equals(uname)) { // 格式: throw+new +异常类名(参数传输字符串) throw new ExceptionDemo01("名字没了你妹的"); } } } }