异常
概念: 就是值程序在执行的过程中,可能会出现的问题,称为异常
生活中的异常 :
计划出去玩 : 出发 -> 去公园 ->散步 -> 吃个烧烤 ->回家
出现的问题 : 散步的时候,下雨了,只能终止计划,提前回家。这个时候,下雨,就是一种异常情况
解决方法 : 玩之前查看天气,如果要下雨,带把雨伞 。带着雨伞 就是 可能出现异常的解决方案
程序中的异常: 程序中出现不正常的情况,跳出的提示
比如如下的例子, 正常按照提示,用户可以输入 1-3的数字,但是有些用户如果输入其他的非数字的字符,程序运行就会发生异常
public class Demo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入1-3之间的整数:");
int i = scanner.nextInt();
switch (i){
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
default:
System.out.println("输入错误");
break;
}
}
}
Java中异常相关的类
为了让程序员能够很好的处理异常错误,Java专门提供了异常类 Throwable,用来处理错误及异常
异常体系结构
Thorwable 父类
--Error 子类,错误类 ,表示严重的问题,程序员一般无法解决
--Exception 子类,异常类,是程序员需要去解决的
----RuntimeException 运行时异常,一般都是程序运行时发生的错误,通过修改代码可以防止异常的出现
----非RuntimeException 编译时异常,必须要处理,否则,程序编译不通过
异常的处理
Java中处理异常,通过5个关键字来实现: try 、catch 、 throw 、 throws 、finally
处理方案 :
1,JVM的默认处理:
把异常的名称、原因、位置等信息输出在控制台,然后终止程序运行
2,自己处理
方式1: try....catch....finally
语法: try{
代码块1;
}catch(ExceptionType1 e){
异常处理代码块1;
}catch(ExceptionType2 e){
异常处理代码块2;
}finally{
最终代码块;
}
如果,将来程序员写的代码,可能会发生异常,就需要将这段代码提前放在try块中。
在catch的后面,跟上将来你的代码中,可能会出现的异常类型类型 ,如果将来真的发生异常了,程序也不会因为异常而终止,只会继续跳转到catch块中继续执行其中的代码。
catch块中的代码,执行完后,会继续执行finally块中的代码
public class Demo02 {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入被除数:");
int num1 = scanner.nextInt();
System.out.println("请输入除数:");
int num2 = scanner.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1/num2);
}catch (InputMismatchException exception){
System.err.println("输入的数据不符合类型规范!");
}catch (ArithmeticException exception){
System.err.println("除数不能为零");
}finally {
//不管程序有没有异常,这里的代码都会执行
System.out.println("程序结束,感谢使用!");
}
}
}
try..catch..finally注意事项
1,整个语法结构中,try块是必须要写的,catch块和finally块是可选的,但是catch和finally至少得有一个,也可以同时出现
2,可以有多个catch块,如果catch的异常类型,存在父子关系,那么父类异常必须放在子类异常的后面
3,多个catch块必须位于try块后,finally块也必须位于所有的catch后面
try...catch块和 return语句的执行:
1,当try块和catch中,都有return语句时,不会影响finally语句的执行
2,如果finally中,指定了return,并且是有返回值的情况,返回值可能会替换try中的return的返回值,所以,finally中的尽量不要加return
public class Demo03 {
public static void main(String[] args) {
System.out.println(operate());
}
public static int operate(){
int num1 = 0;
int num2 = 1;
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入被除数:");
num1 = scanner.nextInt();
System.out.println("请输入除数:");
num2 = scanner.nextInt();
//System.out.println(num1 + "/" + num2 + "=" + num1/num2);
return num1/num2;
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("程序结束!");
//return num1/num2;
}
return 0;
}
}
方式2: 通过throws,将异常抛出。
把自己处理不了的异常,在方法上声明,告诉调用者,这个方法可能会有异常,需要处理
在方法上,通过throws抛出异常之后,调用者,调用后,需要怎么做?
开发的时候,调用的方法上,存在异常,需要怎么解决 ?
(idea中直接alt+enter,选择以下两个方法中的一个处理即可)
1,将异常继续向上抛;一般平时的代码测试可以用这个方式
2,使用try-catch手动捕获异常,进行处理;将来项目开发,尽量都用这种方式
public class Demo04 {
public static void operate() throws Exception{
Scanner scanner = new Scanner(System.in);
System.out.println("请输入被除数:");
int num1 = scanner.nextInt();
System.out.println("请输入除数:");
int num2 = scanner.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1/num2);
System.out.println("程序结束!");
}
}
public class Test {
//在方法上继续抛出异常
public static void main(String[] args) throws Exception {
//手动捕获异常,并处理 或者在方法上继续抛出
//try {
Demo04.operate();
//} catch (Exception e) {
// System.err.println("程序发生了异常!");
// e.printStackTrace();
//}
}
}
Throw
throw是开发者自己定义一个异常(需要跟throws一起配合使用)
throw申明在方法内(自己定义一个异常,来限定一些情况)
throws和throw的区别?
1,throws一般声明在方法体上,throw 声明在方法内部
2,throws用来声明一个方法可能抛出的所有的异常信息,表示将来异常的一种可能性,但并不一定发生异常
throw 则是抛出一个具体的异常类型,throw是抛出了某个异常对象
3,throws通常不需要显式的捕获异常,由系统自动将异常抛给上级方法
throw需要用户自己捕获相关异常,然后再对其处理,最后将异常信息抛出