异常抛出
1. 异常简介
import java.util.ArrayList;public class DemoException1 {public static void main(String[] args) {/*TODO异常:需求:要买菜做饭1.先制定计划做哪些菜 但是计划里面有问题 比如需要做红烧肉,但是菜单里面写的是排骨 -> 编译时期的异常2.计划没问题 菜买回来了 开始做饭,明明要做红烧肉,但是用的是炖锅 -> 表示为运行时期异常3.用铁锅做红烧肉,但是肉放多了,整个锅放了一头猪 装不下 锅太小 -> ERROR (系统性错误无法处理)在Java中异常顶级父类为 Throwable 其子类分为三类1.ERROR 程序运行时,发生的系统性错误2.RuntimeException 程序运行时的一些代码 逻辑错误3.编译异常.. 写代码时期可以避免发生*/// ArrayList<String> list = new ArrayList<>();
// list.add(1);// System.out.println(1/0);// 堆内存空间溢出// java.lang.OutOfMemoryError: Java heap spaceString guo = "";while (true){guo += (guo+"一头猪");}}}
2. 异常种类概述
public class DemoException2 {public static void main(String[] args) {/*TODO异常种类:1.编译时期异常① 代码语法错误 代码的位置存在问题② 代码中的一些类型,存在不匹配编译时期的异常,可以通过当前IDEA开发工具来展示2.运行时期的异常① ArithmeticException 除0错误 / by zero② ArrayIndexOutOfBoundsException 数组访问越界③ ConcurrentModificationException 迭代器的数据长度和数组的长度不一致导致的④ ClassCastException 类型转换错误 一般发生在对象强制类型转换的情况下⑤ NullPointerException 空指针异常 对对象进行调用时,其内存地址指向为空注意:特点属于 RuntimeException 下的一个子类在运行时会报错,报错后整个程序停止运行如果当程序出现问题,需要对当前的错误进行捕获处理比如对于 NullPointerException 异常,如果出现,那么可以对其进行重新创建对象继续通过对象的方法进行调用*/
// System.out.println(1/0);// int[] ints = new int[3];
// System.out.println(ints[3]);Exp exp = null;
// exp.printInfo();// TODO 如果当exp的变量,指向的是为null,那么可以调用其 new 方法重新创建一个对象,赋予给变量if (exp == null) {exp = new Exp();}exp.printInfo();// TODO 上述的方式属于,问题错误没有发生,但是可以提前进行预防// 对于已经发生的错误,如果要进行处理就需要使用 try .. catch 方式进行捕获}// new Student();
}class Exp {public void printInfo() {System.out.println("这是Exp类中的printInfo方法...");}
}
3. Try/Catch
public class DemoTryCatch {public static void main(String[] args) {/*TODO 异常捕获try...catch (异常的类型 变量名)=> 抓,捕获...Java是一个面向对象的语言,所有的异常类 NullPointerException 也是会有一个对象于是需要使用变量调用对象*//*TODOint[] ints = new int[3];System.out.println(ints[3]);对于代码如果发生错误,那么错误的内容包含有三个方面:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3at com.shujia.day11.Demo05TryCatch.main(Demo05TryCatch.java:17)异常类型:ArrayIndexOutOfBoundsException异常提示信息:3错误发生位置:at com.shujia.day11.Demo05TryCatch.main(Demo05TryCatch.java:17)对于排除问题的思路:① 获取完整的日志信息 错误的位置不一定就发生在代码指定的位置② 找到错误的类型 根据类型可以确定当前问题发生的范围,同时也可以根据类型将错误捕获,让程序继续运行③ 根据错误的提示信息,寻找线索 提示信息中一般都会打印一些数据④ 根据代码指定的位置,对其进行debug,重新运行,查看每个变量中的数据是否符合要求⑤ 如果因为自身对程序的了解不够,导致程序问题寻找不到,那么尝试换种方式*/Exp exp = getExp();try {exp.printInfo();// 也可以使用它们的父类Exception}catch (NullPointerException exception){// 如果发生错误了,就可以捕获到错误的对象 对该对象调用其方法
// System.out.println("错误提示信息:"+ exception.getMessage());System.err.println("错误提示信息:"+ exception.getMessage());// 打印整个的错误提示信息exception.printStackTrace();// 如何将日志信息写入到文件中进行保存?}// TODO 当程序被捕获时,那么可以继续运行代码System.out.println("程序执行到这里了....");// TODO 对于多行代码中可能会出现有多个错误,但是也不确定try {System.out.println(3/0);int[] ints = new int[2];System.out.println(ints[2]);// 对于错误类型有两种 ArrayIndexOutOfBoundsException 或者 ArithmeticException}catch (ArrayIndexOutOfBoundsException | ArithmeticException exception){System.out.println("发生错误了...");System.err.println(exception.getMessage());exception.printStackTrace();}/*TODO 对于多种错误类型,可以直接使用父类 Exception 表示由于异常也是一个具体的类,也符合对象的多态特性于是子类异常对象可以指向父类 Exception变量 在调用时,比如 printStackTrace 方法是调用其具体对象的*/try {System.out.println(3/0);int[] ints = new int[2];System.out.println(ints[2]);}catch (Exception exception){
// exception.getMessage();System.out.println("捕获到了一个异常,但是暂时不知道是什么");exception.printStackTrace();}/*给定的异常太过于具体没有捕获到TODO 需求:当不管代码是否执行正常,都要执行某些代码..比如:如果对Mysql数据库进行操作,操作过程中代码出错了但是Mysql的连接需要进行关闭,否则对于Mysql数据库来说,有一个连接被占用了final格式:try{可能发生错误的代码}catch(){当指定的错误类型,被获取到后的操作}finally{不管代码是否有错误,都会执行..}*/try {String s = null;s.split("");System.out.println(3/0);int[] ints = new int[2];System.out.println(ints[2]);}catch (ArrayIndexOutOfBoundsException | ArithmeticException exception){System.out.println("捕获到了一个异常,但是暂时不知道是什么");exception.printStackTrace();}finally {System.out.println("不管程序是否有错误,该代码块中得代码都会被执行...");}System.out.println("该行被打印表示程序正常执行完成...");}// 假设这是另外一个Jar包或者其他程序员开发的代码 不能进行改变public static Exp getExp() {return null;}
}
4. 自定义异常
public class DemoMyException {// TODO 对于main方法 也可以进行异常抛出,但是一旦遇到异常,程序终止public static void main(String[] args) throws MyDefineException {/*TODO 如果想要定义一个自定义的错误类型throw:通过该关键字可以 抛出一个异常的对象,让其产生错误*/try {/*com.shujia.day11.MyDefineException: 这是自定义的异常at com.shujia.day11.Demo06MyException.main(Demo06MyException.java:11)*/throw new MyDefineException("这是自定义的异常");} catch (MyDefineException exception) {System.out.println(exception.getMessage());exception.printStackTrace();}/*TODO 当在fun函数中定义了一个错误的发生位置,那么对于main方法中,并没有提示其错误那么如何让main方法知道fun函数中可能会发生错误?可以使用throws对异常进行抛出,意思表达为当程序中出现问题,自己不处理交给调用方进行处理由于在main方法中进行调用,那么就需要在main中进行处理*/
// System.out.println(3/0);// try {
// fun(3, 0); // 经过捕获之后就没有异常了
// }catch (MyDefineException exception){
// exception.printStackTrace();
// }fun(2, 0);System.out.println("程序是否能打印改行?");}// public static void fun(int a, int b) {
// TODO 方法内不处理,交给调用方进行处理public static void fun(int a, int b) throws MyDefineException,NullPointerException {if (b == 0) {// 直接处理由于有 throw 执行到该处时肯定会发生错误,程序退出...throw new MyDefineException("除数不能为零,抛出异常,请检查逻辑");} else {System.out.println(a / b);}// TODO 方法内自行处理
// if (b == 0) {
// try {
// throw new MyDefineException("除数不能为零,抛出异常,请检查逻辑");
// } catch (MyDefineException exception) {
// exception.printStackTrace();
// }
// } else {
// System.out.println(a / b);
// }}
}class MyDefineException extends Exception {// 如果当遇到自定义的类型时,想要去打印自定义的信息怎么做// 打印信息 可以使用 getMessage()public MyDefineException(String message) {super(message);}
}
5. 异常总结
public class DemoExceptionTxt {public static void main(String[] args) {/*TODO异常操作的总结:1.对于可能会发生错误的代码处理方式① 使用 try catch 进行捕获异常 程序不会终止如果有必须要执行的代码,可以放到 finally 代码块中② 使用 throws 对可能发生的异常进行抛出,交给调用方进行处理如果调用方也不处理,那么遇到错误,程序会终止2.如果想定义错误1.构建一个自定义异常类继承于 Exception 或者其子类2. 通过 throw 方法触发 其异常类的对象finally的作用用于释放资源,在IO流操作和数据库操作中会见到: 比如对Mysql连接进行关闭操作TODO throws和throw的区别:throws用在方法声明后面,跟的是异常类名可以跟多个异常类名,用逗号隔开表示抛出异常,由该方法的调用者来处理throws表示出现异常的一种可能性,并不一定会发生这些异常throw用在方法体内,跟的是异常对象名只能抛出一个异常对象名表示抛出异常,由方法体内的语句处理throw则是抛出了异常,执行throw则一定抛出了某种异常异常可以用埋雷、排雷的方式理解*//*如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后。finally代码是必须要执行的,是在return之前,函数执行完成之前执行*/System.out.println(fun());}public static int fun(){try {System.out.println("return之前...");return 0;
// System.out.println("return之后...");}catch (Exception exception){System.out.println("异常被捕获...");}finally {System.out.println("finally代码被执行...");}return 1;}
}