Java中的异常处理,一文学完Java异常
异常处理
目录:
-
try…catch…
-
异常处理关键字try{ }catch{ }finally{ }
-
异常处理关键字多重catch
-
异常处理关键字try{ }finally{ }
-
异常的声明 throws关键字
-
抛出异常 Throw
-
自定义异常
-
带有异常声明的方法的覆盖(重写)
第一节 try…catch…
一、样式
Try{…可能出现异常的代码…}
catch(Exception e){…异常进行处理的相关代码getMessage(),printStackTrace等…}
二、出现的情况
第一种:正常请求,不出现异常
import java.util.Scanner; public class Exception1 { public static void main(String[] args) { Scanner input=new Scanner(System.in); int result=0; // try { System.out.println("请输入第一个数字:"); int n1 = input.nextInt(); System.out.println("请输入第二个数字:"); int n2 = input.nextInt(); result = n1 / n2; // } catch (Exception e) { // //异常的捕获 // e.printStackTrace(); // System.out.println(e.getMessage()); //} System.out.println("程序运行结果是:"+result); System.out.println("程序运行结束了。。。"); } }
即正常输入符合基本运算规律的数字
第二种:出现异常并进行处理
1 import java.util.Scanner; 2 3 4 public class Exception1 { 5 6 public static void main(String[] args) { 7 8 Scanner input=new Scanner(System.in); 9 10 int result=0; 11 12 try { 13 14 System.out.println("请输入第一个数字:"); 15 16 int n1 = input.nextInt(); 17 18 System.out.println("请输入第二个数字:"); 19 20 int n2 = input.nextInt(); 21 22 result = n1 / n2; 23 24 } catch (Exception e) { 25 26 //异常的捕获 27 28 e.printStackTrace(); 29 30 System.out.println(e.getMessage()); 31 32 } 33 34 System.out.println("程序运行结果是:"+result); 35 36 System.out.println("程序运行结束了。。。"); 37 38 } 39 40 }
如果程序在运行过程中出现了不符合基本运算规律的数字,比如10/0,或者a等字符等,此时出现异常
第三种:异常的类型不匹配
1 import java.util.Scanner; 2 3 public class Exception1 { 4 public static void main(String[] args) { 5 Scanner input=new Scanner(System.in); 6 int result=0; 7 try { 8 System.out.println("请输入第一个数字:"); 9 int n1 = input.nextInt();//InputMismatchException异常 10 System.out.println("请输入第二个数字:"); 11 int n2 = input.nextInt(); 12 result = n1 / n2;//ArethmicException异常 13 } catch (NullPointerException e) {//空指针异常 14 //异常的捕获 15 e.printStackTrace(); 16 System.out.println(e.getMessage()); 17 } 18 System.out.println("程序运行结果是:"+result); 19 System.out.println("程序运行结束了。。。"); 20 } 21 } 22 //无法捕获异常
即可能不以Exception创建对象而使用Exception的子类进行创建,比如说上述代码是以空指针异常NullPointException创建的对象,而代码中可能出现是算术异常ArethmicException或者数据不匹配异常InputMismatchException。
异常处理关键字try{ }catch{ }finally{ }
一、语句语法
Try{…}catch{…}finally{…}
1 import java.util.Scanner; 2 3 public class Exception1 { 4 public static void main(String[] args) { 5 Scanner input=new Scanner(System.in); 6 int result=0; 7 try { 8 System.out.println("请输入第一个数字:"); 9 int n1 = input.nextInt(); 10 System.out.println("请输入第二个数字:"); 11 int n2 = input.nextInt(); 12 result = n1 / n2; 13 } catch (Exception e) { 14 //异常的捕获 15 e.printStackTrace(); 16 System.out.println(e.getMessage()); 17 }finally { 18 System.out.println("通常情况下,finally用来释放资源,且无论是否产生异常都可以执行,唯一一个不会执行的情况是退出了java的虚拟机"); 19 } 20 System.out.println("程序运行结果是:"+result); 21 System.out.println("程序运行结束了。。。"); 22 } 23 }
二、注意事项
-
finally块是否发生异常都会执行,可以释放资源
-
finally不执行的唯一情况,推出了JVM虚拟机
下面是对于2. 的演示实例
1 import java.util.Scanner; 2 3 public class Exception1 { 4 public static void main(String[] args) { 5 Scanner input=new Scanner(System.in); 6 int result=0; 7 try { 8 System.out.println("请输入第一个数字:"); 9 int n1 = input.nextInt(); 10 System.out.println("请输入第二个数字:"); 11 int n2 = input.nextInt(); 12 result = n1 / n2; 13 //手动推出JVM虚拟机 14 System.exit(0); 15 } catch (Exception e) { 16 //异常的捕获 17 e.printStackTrace(); 18 System.out.println(e.getMessage()); 19 }finally { 20 System.out.println("通常情况下,finally用来释放资源,且无论是否产生异常都可以执行,唯一一个不会执行的情况是退出了java的虚拟机"); 21 } 22 System.out.println("程序运行结果是:"+result); 23 System.out.println("程序运行结束了。。。"); 24 } 25 }
异常处理关键字多重catch
一、语法样例
Try{ }catch(异常类型1){ }.. catch(异常类型2){ }.. catch(异常类型3){ }..finally(){ }
二.注意事项
1.子类异常在前,父类在后
2.发生异常按顺序,逐个匹配
3.只执行第一个与异常类匹配的catch语句
4.finally可以根据实际需要可以添加也可以不添加
三、示例
1 import java.util.InputMismatchException; 2 import java.util.Scanner; 3 4 public class Exception1 { 5 public static void main(String[] args) { 6 Scanner input=new Scanner(System.in); 7 int result=0; 8 try { 9 System.out.println("请输入第一个数字:"); 10 int n1 = input.nextInt(); 11 System.out.println("请输入第二个数字:"); 12 int n2 = input.nextInt(); 13 result = n1 / n2; 14 }catch (ArithmeticException a){ 15 System.out.println("这是一个算术方面的异常情况"); 16 }catch (InputMismatchException i){ 17 System.out.println("这是一个输入不匹配的异常"); 18 } 19 catch (Exception e) { 20 //异常的捕获 21 e.printStackTrace(); 22 System.out.println(e.getMessage()); 23 System.out.println("未知错误。。"); 24 } 25 finally { 26 System.out.println("通常情况下,finally用来释放资源,且无论是否产生异常都可以执行,唯一一个不会执行的情况是退出了java的虚拟机"); 27 } 28 System.out.println("程序运行结果是:"+result); 29 System.out.println("程序运行结束了。。。"); 30 } 31 }
异常处理关键字try{ }finally{ }
一、应用
一般用于底层代码,只释放资源,不进行捕获,异常会按照调用顺序向上找到相关可捕获的代码或者交给JVM
二、案例演示:
1 import java.util.InputMismatchException; 2 3 import java.util.Scanner; 4 5 public class Exception2 { 6 public static void main(String[] args) { 7 try { 8 divide(); 9 } 10 catch (Exception e){ 11 System.out.println("该异常被捕获:"+e.getMessage()); 12 } 13 } 14 public static void divide(){ 15 Scanner input=new Scanner(System.in); 16 int result=0; 17 try { 18 System.out.println("请输入第一个数字:"); 19 int n1 = input.nextInt(); 20 System.out.println("请输入第二个数字:"); 21 int n2 = input.nextInt(); 22 result = n1 / n2; 23 }catch (ArithmeticException a){ 24 System.out.println("这是一个算术方面的异常情况"); 25 }catch (InputMismatchException i){ 26 System.out.println("这是一个输入不匹配的异常"); 27 } 28 catch (Exception e) { 29 //异常的捕获 30 e.printStackTrace(); 31 System.out.println(e.getMessage()); 32 System.out.println("未知错误。。"); 33 } 34 finally { 35 System.out.println("通常情况下,finally用来释放资源,且无论是否产生异常都可以执行,唯一一个不会执行的情况是退出了java的虚拟机"); 36 } 37 System.out.println("程序运行结果是:"+result); 38 System.out.println("程序运行结束了。。。"); 39 } 40 }
解释:在这段代码中,我输入被除数7和除数2,这种情况下,主函数main()调用了divide()函数,此时divide()出现了错误,但是divide()本身不会对这汇总情况进行处理,于是向上抛出给了主函数main(),与此同时,main()中有捕获方法catch,此时进行了捕获。
同时我们也可以试想,如果主函数也无法进行捕获呢?它会交给JVM进行错误打印,同时直接对程序进行中断。
异常的声明 throws关键字
一、使用原则:
底层代码向上声明或抛出异常,最上一层一定要处理否则交给JVM程序中断
二、演示案例
1 import java.util.Scanner; 2 3 public class Exception3 { 4 public static void main(String[] args) { 5 try {divide();}catch (Exception e){ 6 System.out.println(e.getMessage()); 7 } 8 }//此时异常由divide传递到了主函数中,如果不继续向上抛出的话,主函数必须对异常进行捕获 9 public static void divide() throws Exception{ 10 Scanner input=new Scanner(System.in); 11 System.out.println("Please input the first number"); 12 int num1=input.nextInt(); 13 System.out.println("Please input the second number"); 14 int num2=input.nextInt(); 15 int result=num1/num2; 16 System.out.println("result is :"+result); 17 System.out.println("The end of the software"); 18 } 19 }
如果不想在主函数中加入TRY CATCH语句,同时又不想他进行报错。我们可以在PSVM后面加throws Exception,把异常继续向上抛出给JVM
抛出异常 Throw
一、概念解释及语法
除系统自动抛出异常外,有些问题要程序员自行抛出异常
语法:throw 抛出对象
二、案例演示
这里新建了两个Java类,其中Person类包含人的年龄、性别、名字,并规定,人的年龄在0-120之间是有效的,而性别只有男和女有效,其余的会显示抛出异常。
主函数会调用这个类并新建对象给这三个属性进行赋值
Person类
1 public class Person { 2 int age; 3 String name; 4 String sex; 5 6 7 public Person() { 8 } 9 10 public Person(int age, String name, String sex) { 11 this.age = age; 12 this.name = name; 13 this.sex = sex; 14 } 15 16 public int getAge() { 17 return age; 18 } 19 20 public void setAge(int age) { 21 if (age>=0&&age<=120){ 22 this.age = age;} 23 24 else{ 25 throw new RuntimeException("年龄异常抛出"); 26 } 27 } 28 29 public String getName() { 30 return name; 31 } 32 33 public void setName(String name) { 34 this.name = name; 35 } 36 37 public String getSex() { 38 return sex; 39 } 40 41 public void setSex(String sex) { 42 if (sex.equals("男")||sex.equals("女")){ 43 this.sex = sex;}else { 44 //抛出 45 throw new RuntimeException("性别错误"); 46 } 47 } 48 49 @Override 50 public String toString() { 51 return "Person{" + 52 "age=" + age + 53 ", name='" + name + '\'' + 54 ", sex='" + sex + '\'' + 55 '}'; 56 } 57 }
主类main
1 public class TestPerson { 2 3 4 public static void main(String[] args) { 5 Person p=new Person(); 6 p.setAge(20); 7 //p.setName("C"); 8 p.setSex("e"); 9 } 10 }
运行后会发现:这里的性别会显示抛出异常,因为我们设置了性别只有男和女才被视作为有效。
Ps:我们知道
|
RuntimeException |
运行时异常 |
可处理可不处理 |
|
CheckedException |
检查时异常 |
必须处理 |
如果把原文中的RuntimeException全部变换为Exception会出现什么结果呢?
结果必然必然会是报错
处理方式:1.在set方法出加throws关键字向上抛出,2.加Try..Catch..语句
同样的在主类调用时同样需要重复做这一步骤。
实例如下:
1 public class Person { 2 int age; 3 String name; 4 String sex; 5 6 public Person() { 7 } 8 9 public Person(int age, String name, String sex) { 10 this.age = age; 11 this.name = name; 12 this.sex = sex; 13 } 14 15 public int getAge() { 16 return age; 17 } 18 19 public void setAge(int age) throws Exception{ 20 if (age>=0&&age<=120){ 21 this.age = age;}else{ 22 throw new Exception("年龄异常抛出"); 23 } 24 } 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public String getSex() { 35 return sex; 36 } 37 38 public void setSex(String sex) throws Exception{ 39 if (sex.equals("男")||sex.equals("女")){ 40 this.sex = sex; 41 }else { 42 //抛出 43 throw new Exception("性别错误"); 44 } 45 } 46 47 @Override 48 public String toString() { 49 return "Person{" + 50 "age=" + age + 51 ", name='" + name + '\'' + 52 ", sex='" + sex + '\'' + 53 '}'; 54 } 55 }
1 public class TestPerson { 2 public static void main(String[] args) throws Exception{ 3 Person p=new Person(); 4 p.setAge(20); 5 p.setName("C"); 6 p.setSex("男"); 7 8 } 9 }
自定义异常
一、相关要求
-
要继承Exception或者他的子类,常用runtimeException
-
必要构造方法,无参构造和(String Message)
作用:报错时名字更加贴切
二、示例
快速添加构造方法:
IDEA:Alt+insert
Eclipse:Alt+shift+s
AgeException类
SexException类
Person类
TestPerson类
AgeException类
1 public class AgeException extends RuntimeException{ 2 public AgeException() { 3 } 4 5 public AgeException(String message) { 6 super(message); 7 } 8 9 public AgeException(String message, Throwable cause) { 10 super(message, cause); 11 } 12 13 public AgeException(Throwable cause) { 14 super(cause); 15 } 16 17 public AgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 18 super(message, cause, enableSuppression, writableStackTrace); 19 } 20 }
SexException类
1 public class SexException extends RuntimeException{ 2 public SexException() { 3 } 4 5 public SexException(String message) { 6 super(message); 7 } 8 9 public SexException(String message, Throwable cause) { 10 super(message, cause); 11 } 12 13 public SexException(Throwable cause) { 14 super(cause); 15 } 16 17 public SexException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 18 super(message, cause, enableSuppression, writableStackTrace); 19 } 20 }
Person类
1 public class Person { 2 int age; 3 String name; 4 String sex; 5 6 public Person() { 7 } 8 9 public Person(int age, String name, String sex) { 10 this.age = age; 11 this.name = name; 12 this.sex = sex; 13 } 14 15 public int getAge() { 16 return age; 17 } 18 19 public void setAge(int age) throws Exception{ 20 if (age>=0&&age<=120){ 21 this.age = age;}else{ 22 throw new AgeException("年龄异常抛出"); 23 } 24 } 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public String getSex() { 35 return sex; 36 } 37 38 public void setSex(String sex) throws Exception{ 39 if (sex.equals("男")||sex.equals("女")){ 40 this.sex = sex; 41 }else { 42 //抛出 43 throw new SexException("性别错误"); 44 } 45 } 46 47 @Override 48 public String toString() { 49 return "Person{" + 50 "age=" + age + 51 ", name='" + name + '\'' + 52 ", sex='" + sex + '\'' + 53 '}'; 54 } 55 }
TestPerson类
1 public class TestPerson { 2 public static void main(String[] args) throws Exception{ 3 Person p=new Person(); 4 p.setAge(20); 5 p.setName("C"); 6 p.setSex("男"); 7 8 } 9 }
带有异常声明的方法的覆盖(重写)
一、
方法名、参数列表、返回值类型一定和父类相同(同重写)
二、
子类的访问修饰符和父类相同或比父类宽
例如:子类是public,父类必须是public
子类是public,父类是private
三、
子类中的方法,不可抛出比父类更多,更宽的检查时异常
例如:父类是FileNotFoundException,子类是Exception
即子类的错误类别应当包含父类,或者说父类的错误类别应当是子类的错误类别的子类。

浙公网安备 33010602011771号