程序在运行过程中出现的不正常的事件,它会中断正在运行的程序。
异常处理对出现的异常进行相应的 *** 作,使得程序可以正常继续运行。
捕获异常 try:有可能产生异常的代码块。catch:对出现的异常进行匹配,匹配成功后对这个异常进行处理的方案。finally:无论发生任何情况,都能执行的代码块,如果 try 或者 catch 中存在 return 必须等待 finally 执行完成后在 return 。 捕获异常的三种情况/*
情况1
代码有可能产生异常,也进行了异常处理方案,但是实际运行中没有发生异常,那么catch块就不会执行。
*/
public static void a() {
System.out.print("请输入除数:");
int divisor = scan.nextInt();
System.out.print("请输入被除数:");
int dividend = scan.nextInt();
try {
// 可能产生异常的代码块
int result = divisor / dividend; // 这一段内容可能产生异常
System.out.println("运算结果是:" + result);
} catch (ArithmeticException e) { // 对数学异常进行处理的方案
System.out.println("你的被除数不能为0");
}
System.out.println("我是异常处理之后的代码块!");
}
/*
情况2
代码有可能产生异常,结果就是产生了异常,匹配catch块语句,执行对应catch中的内容,程序继续执行。
*/
public static void b() {
int[] array = {1, 2, 3, 4, 5};
System.out.print("请选择你要的元素下标:");
int index = scan.nextInt();
try {
int result = array[index]; // 有可能产生异常 系统自动产生了某种类型的异常对象
System.out.println("选择了" + index + ",对应的值是:" + result);
} catch (Exception e) {
System.out.println("数组越界了!");
}
System.out.println("我是异常处理之后的代码块!");
}
/*
情况3
代码有可能产生异常,产生了异常,匹配catch处理方案,方案未匹配成功,异常处理流失败,中断运行的程序!
*/
public static void c() {
System.out.println("请输入一个数字:");
try {
int a = scan.nextInt(); // 有可能产生异常
System.out.println("输入的数字:" + a);
} catch (ArithmeticException e) { // 当出现数学异常时的处理方案
System.out.println("你的代码出现了异常!");
}
System.out.println("我是异常处理之后的代码块!");
}
多异常的处理情况
/*
多行代码中都存在异常,Java支持多重catch块来分别处理这些异常
多重catch块的写法,分别处理不同的异常情况
执行顺序:
自顶向下进行匹配,
匹配成功执行对应catch块,结束异常处理
匹配失败继续匹配下边的catch块,依此类推,如果都未匹配成功则异常处理失败
⚠️ 顺序是按照先书写子异常,后书写父异常的方式进行,一般都会在最后书写一个Exception来应对未知情况
*/
int[] array = {11, 2, 3, 4, 5, 0, 6, 7};
System.out.print("请输入索引号:");
try {
// 这一段代码可能会产生异常 并且可能会产生不同的异常 但是一次只能产生一个异常
int index = scan.nextInt(); // 输入不合法 例如输入了一个abc
int num = array[index]; // 越界异常
int result = 15 / num; // 数学异常
System.out.println(15 + "除以" + num + "结果是:" + result);
} catch (InputMismatchException e) {
System.out.println("输入的内容必须是数字!");
} catch (IndexOutOfBoundsException e) {
System.out.println("超过了索引范围!");
} catch (ArithmeticException e) {
System.out.println("除数不能为0!");
}
System.out.println("这是异常处理之后的代码块!");
多异常中catch块的顺序问题
int[] array = {11, 7, 3, 4, 5, 0, 6, 7};
System.out.print("请输入索引:");
try {
int index = scan.nextInt();
int num = array[index];
int result = 14 / num;
System.out.println(15 + "除以" + num + "结果是:" + result);
} catch (Exception e) { // 因为这里会处理所有的异常情况,都匹配上了
System.out.println("出现了异常情况!");
} catch (InputMismatchException e) { // ❌ 不可能达到的语句
System.out.println("输入的内容必须是数字!");
} catch (IndexOutOfBoundsException e) {// ❌ 不可能达到的语句
System.out.println("超过了索引范围!");
} catch (ArithmeticException e) {// ❌ 不可能达到的语句
System.out.println("除数不能为0!");
}
// ⚠️ catch块的设置,遵循先子类后父类的原则!
finally块
在异常处理中,代表不论发生什么情况永远都会执行的代码块。
// 能够处理异常
public void a() {
try {
int a = (int) (Math.random() * 2); //[0,1]
System.out.println("产生的随机数:" + a);
int result = 10 / a; // 可能产生异常
System.out.println("结果是:" + result);
} catch (ArithmeticException e) {
System.out.println("除数不能为零!");
} finally {
System.out.println("不管发生什么情况,我都会执行!");
}
System.out.println("代码之外的内容");
}
// 不能够处理异常
public void b() {
try {
int a = (int) (Math.random() * 2); //[0,1]
System.out.println("产生的随机数:" + a);
int result = 10 / a; // 可能产生异常
System.out.println("结果是:" + result);
} catch (NullPointerException e) { // 这里肯定匹配不上,异常处理失败,中断程序运行
System.out.println("空指针异常!");
} finally {
System.out.println("不管发生什么情况,我都会执行!");
}
System.out.println("代码之外的内容");
}
抛出异常
throw:手动抛出一个异常
thorws:声明抛出去的异常是什么类型的,告诉别人这里有一个异常
// 抛出异常
public class DemoG {
/*
如果传递进来的len小于7 抛出一个异常
*/
public static void a(int len) throws Exception{ // throws 声明此方法扔出去的异常是什么类型的
if (len < 7) {
// 手动抛出一个异常
// 产生一个异常对象,手动产生一个异常对象
Exception e = new Exception("len的值必须大于等于7");
// 扔出异常
throw e;
}
System.out.println("我是方法a,接收的参数:" + len);
}
// b方法调用了a方法 它抛出了异常对象 ,b方法也将这个异常抛出
// 相当于a方法的异常b方法并不处理
public static void b(int len) throws Exception{
a(len);
}
// c方法处理了异常
public static void c(int len) {
try {
b(len);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
c(4);
}
}
异常的体系结构
Throwable
是Java语言中所有错误和异常的父类。
Error
指的是一个合理的应用程序不应该试图捕获的严重问题,它一般都不是程序员负责处理的情况,类似于内存溢出。
Exception
程序在运行过程中出现的不正常的事件,它会中断正在运行的程序。
运行时异常
代码编译通过,但是在运行时没有通过的情况,就叫做运行时异常,它有一个共有的父类RuntimeException。
编译时异常
代码在编译时都没有通过的情况,就叫做编译时异常,它没有共有父类。
常见异常
异常 | 描述 |
---|---|
NullPointerException | 空指针异常,当程序试图在需要对象时使用null,则抛出异常 |
ArithmeticException | 数学异常,不符合运算条件时,则抛出异常 |
IndexOutOfBoundsException | 越界异常,超出了索引范围,则抛出异常 |
InputMismatchException | 输入异常,输入内容不合法,则抛出异常 |
NumberFormatException | 类型转换异常,类型转换不符合要求时,则抛出异常 |
IOException | IO流异常 |
SQLException | 数据库异常 |
ClassNotFoundException | 类没有找到异常 |
FileNotFoundException | 文件没有找到异常 |
// try-catch-finally的执行顺序
// 面试题1
public static int a() {
int a = 1;
try {
a++;
System.out.println("try的代码块,a:" + a);
} catch (Exception e) {
a--;
System.out.println("catch的代码块,a:" + a);
} finally {
a = 5;
System.out.println("finally的代码块,a:" + a);
}
return a;
}
// 面试题2
public static int b() {
int a = 1;
try {
a++;
System.out.println("try的代码块,a:" + a);
int b = a / 0; // 出现了异常
} catch (Exception e) {
a--;
System.out.println("catch的代码块,a:" + a);
} finally {
a = 5;
System.out.println("finally的代码块,a:" + a);
}
return a;
}
// 面试题3
public static int c() {
int a = 1;
try {
a++;
System.out.println("try的代码块,a:" + a);
return a; // 如果有finally 必须执行finally后在return
} catch (Exception e) {
a--;
System.out.println("catch的代码块,a:" + a);
} finally {
a = 5;
System.out.println("finally的代码块,a:" + a);
}
return a;
}
// 面试题4
public static int d() {
int a = 1;
try {
a++;
System.out.println("try的代码块,a:" + a);
return a; // 如果有finally 必须执行finally后在return
} catch (Exception e) {
a--;
System.out.println("catch的代码块,a:" + a);
} finally {
a = 5;
System.out.println("finally的代码块,a:" + a);
return a; // 存在return 就执行finally的return不会在回去执行try中的return
}
}
异常的常见方法
public static void a(){
try {
int a = 9 / 0;
} catch (Exception e) {
// 获取到异常的提示信息
String message = e.getMessage();
System.out.println(message);
}
}
public static void b(){
try {
int a = 9 / 0;
} catch (Exception e) {
// 输出异常的堆栈错误信息
e.printStackTrace();
}
System.out.println("我的程序没有中断运行");
}
自定义异常
// 自定义异常
// 书写一个类 继承Exception或者它的子类
public class DemoH extends Exception{
// 通过构造器给message赋值 ,可以不写
public DemoH(String message){
super(message);
}
// 重写了getMessage方法,可以不重写
public String getMessage() {
System.out.println("我是自定义的异常");
return super.getMessage();
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)