首页 > 编程语言 >java-异常处理

java-异常处理

时间:2023-11-12 21:34:31浏览次数:43  
标签:java 处理 System catch println 异常 public out

第九章 java异常处理

习题的引入

【1】代码:

 

 1 public class Test {
 2     //这是一个main方法,是程序的入口:
 3     public static void main(String[] args) {
 4         //实现一个功能:键盘录入两个数,求商:
 5         Scanner sc = new Scanner(System.in);
 6         System.out.println("请录入第一个数:");
 7         int num1 = sc.nextInt();
 8         System.out.println("请录入第二个数:");
 9         int num2 = sc.nextInt();
10         System.out.println("商:"+num1/num2);
11     }
12 }

 

运行结果:

 

测试过程发现问题:

录入的数据应为int类型,但是录入非int类型数据的时候,出异常:

 

除数为0的时候:

 

异常:Exception:在程序的运行过程中,发生了不正常的现象,阻止了程序的运行,我们称之为发生异常。

 

通过if-else解决异常

 1 package com.llh;
 2 
 3 import java.util.Scanner;
 4 
 5 
 6 public class Test {
 7     //这是一个main方法,是程序的入口:
 8     public static void main(String[] args) {
 9         //实现一个功能:键盘录入两个数,求商:
10         Scanner sc = new Scanner(System.in);
11         System.out.println("请录入第一个数:");
12         if(sc.hasNextInt()){
13             int num1 = sc.nextInt();
14             System.out.println("请录入第二个数:");
15             if(sc.hasNextInt()){
16                 int num2 = sc.nextInt();
17                 if(num2 == 0){
18                     System.out.println("对不起,除数不能为0");
19                 }else{
20                     System.out.println("商:"+num1/num2);
21                 }
22             }else{
23                 System.out.println("对不起,你录入的不是int类型的数据!");
24             }
25         }else{
26             System.out.println("对不起,你录入的不是int类型的数据!");
27         }
28     }
29 }

 

用if-else堵漏洞的缺点:

(1)代码臃肿,业务代码和处理异常的代码混在一起。

(2)可读性差

(3)程序员需要花费大量的经历来维护这个漏洞

(4)程序员很难堵住所有的漏洞。

 

try-catch

【1】基于if-else处理异常缺点太多,所以java中专门出了一个异常处理机制:

“异常三连”  try-catch-finally

【2】异常出现了以后怎么看:

 

【3】捕获异常: try-catch

对应代码:

 1 public class Test2 {
 2     public static void main(String[] args) {
 3         //实现一个功能:键盘录入两个数,求商:
 4         try{
 5             Scanner sc = new Scanner(System.in);
 6             System.out.println("请录入第一个数:");
 7             int num1 = sc.nextInt();
 8             System.out.println("请录入第二个数:");
 9             int num2 = sc.nextInt();
10             System.out.println("商:"+num1/num2);
11         }catch(Exception ex){
12             System.out.println("对不起,程序出现异常!");
13         }
14         System.out.println("----谢谢你使用计算器111");
15         System.out.println("----谢谢你使用计算器222");
16         System.out.println("----谢谢你使用计算器333");
17         System.out.println("----谢谢你使用计算器444");
18         System.out.println("----谢谢你使用计算器555");
19         System.out.println("----谢谢你使用计算器666");
20     }
21 }

 

原理:

把可能出现异常的代码放入try代码块中,然后将异常封装为对象,被catch后面的()中的那个异常对象接收,接收以后:执行catch后面的{}里面的代码,然后try-catch后面的代码,该怎么执行就怎么执行。

 

详细说一下:

(1)try中没有异常,catch中代码不执行。

(2)try中有异常,catch进行捕获:

如果catch中异常类型和你出的异常类型匹配的话:走catch中的代码--》进行捕获

如果catch中异常类型和你出的异常类型不匹配的话:不走catch中的代码--》没有捕获成功,程序相当于遇到异常了,中断了,后续代码不执行

 

注意:

 

(1)try中如果出现异常,然后用catch捕获成功的话,那么try中后续的代码是不会执行的。

(2)如果catch捕获异常成功,那么try-catch后面的代码该执行还是执行没有影响。

 

catch中如何处理异常

 1 package com.llh;
 2 
 3 import java.util.Scanner;
 4 
 5 
 6 public class Test3 {
 7     public static void main(String[] args) {
 8         //实现一个功能:键盘录入两个数,求商:
 9         try{
10             Scanner sc = new Scanner(System.in);
11             System.out.println("请录入第一个数:");
12             int num1 = sc.nextInt();
13             System.out.println("请录入第二个数:");
14             int num2 = sc.nextInt();
15             System.out.println("商:"+num1/num2);
16         }catch(Exception ex){
17             //第一种处理:什么都不写,什么都不做
18             //第二种处理:输出自定义异常信息
19             //System.out.println("对不起,你的代码有问题!");
20             //第三种处理:打印异常信息:
21             /*(1)调用toString方法,显示异常的类名(全限定路径)*/
22             /*System.out.println(ex);
23             System.out.println(ex.toString());*/
24             /*(2)显示异常描述信息对应的字符串,如果没有就显示null
25             System.out.println(ex.getMessage());*/
26             /*(3)显示异常的堆栈信息:将异常信息捕获以后,在控制台将异常的效果给我们展示出来,方便我们查看异常*/
27             /* ex.printStackTrace();*/
28             //第四种处理:抛出异常:
29             throw ex;
30         }
31         System.out.println("----谢谢你使用计算器111");
32     }
33 }

 

try-catch-finally

【1】在什么情况下,try-catch后面的代码不执行?

(1)throw抛出异常的情况

(2)catch中没有正常的进行异常捕获

(3)在try中遇到return

 

【2】怎么样才可以将 try-catch后面的代码  必须执行?

只要将必须执行的代码放入finally中,那么这个代码无论如何一定执行。

 

【3】return和finally执行顺序?

先执行finally最后执行return

 

【4】什么代码会放在finally中呢?

关闭数据库资源,关闭IO流资源,关闭socket资源。

 

【5】有一句话代码很厉害,它可以让finally中代码不执行!

System.exit(0);//终止当前的虚拟机执行

 

代码:

 1 package com.llh;
 2 
 3 import java.util.Scanner;
 4 
 5 
 6 public class Test3 {
 7     public static void main(String[] args) {
 8         //实现一个功能:键盘录入两个数,求商:
 9         try{
10             Scanner sc = new Scanner(System.in);
11             System.out.println("请录入第一个数:");
12             int num1 = sc.nextInt();
13             System.out.println("请录入第二个数:");
14             int num2 = sc.nextInt();
15             System.out.println("商:"+num1/num2);
16             System.exit(0);//终止当前的虚拟机执行
17             return;
18         }catch(ArithmeticException ex){
19             //throw ex;
20         }finally {
21             System.out.println("----谢谢你使用计算器111");
22         }
23     }
24 }

 

 

多重catch

【1】try中出现异常以后,将异常类型跟catch后面的类型依次比较,按照代码的顺序进行比对,执行第一个与异常类型匹配的catch语句

【2】一旦执行其中一条catch语句之后,后面的catch语句就会被忽略了!

【3】在安排catch语句的顺序的时候,一般会将特殊异常放在前面(并列),一般化的异常放在后面。

先写子类异常,再写父类异常。

【4】在JDK1.7以后,异常新处理方式:可以并列用|符号连接:

 

 1 package com.llh;
 2 
 3 import java.util.InputMismatchException;
 4 import java.util.Scanner;
 5 
 6 
 7 public class Test4 {
 8     public static void main(String[] args) {
 9         //Integer
10         //实现一个功能:键盘录入两个数,求商:
11         try{
12             Scanner sc = new Scanner(System.in);
13             System.out.println("请录入第一个数:");
14             int num1 = sc.nextInt();
15             System.out.println("请录入第二个数:");
16             int num2 = sc.nextInt();
17             System.out.println("商:"+num1/num2);
18         }catch(ArithmeticException ex){
19             System.out.println("对不起,除数不可以为0");
20         }catch(InputMismatchException ex){
21             System.out.println("对不起,你录入的数据不是int类型的数据");
22         }catch(Exception ex){
23             System.out.println("对不起,你的程序出现异常");
24         }finally {
25             System.out.println("----谢谢你使用计算器111");
26         }
27     }
28 }

 

异常的分类

【1】层次结构:

 

注意:程序中语法错误,逻辑错误  都不属于上面的Error,Exception

 

【2】运行时异常:

 1 public class Test5 {
 2     //这是一个main方法,是程序的入口:
 3     public static void main(String[] args) {
 4         //运行时异常:
 5         int[] arr = {1,2,3};
 6         System.out.println(arr.length);
 7         /*int[] arr2 = null;
 8         System.out.println(arr2.length);*/
 9         System.out.println(arr[10]);
10     }
11 }

 

【3】检查异常:

处理方式1:try-catch嵌套try-catch

 1 public class Test6 {
 2     //这是一个main方法,是程序的入口:
 3     public static void main(String[] args) {
 4         //检查异常:
 5         try {
 6             try {
 7                 Class.forName("com.msb.test01.Test").newInstance();
 8             } catch (InstantiationException e) {
 9                 e.printStackTrace();
10             } catch (IllegalAccessException e) {
11                 e.printStackTrace();
12             }
13         } catch (ClassNotFoundException e) {
14             e.printStackTrace();
15         }
16     }
17 }
 

处理方式2:多重catch

 1 public class Test6 {
 2     //这是一个main方法,是程序的入口:
 3     public static void main(String[] args) {
 4         //检查异常:
 5         try {
 6             Class.forName("com.msb.test01.Test").newInstance();
 7         } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
 8             e.printStackTrace();
 9         }
10     }
11 }

 

处理方式3:throws

1 public class Test6 {
2     //这是一个main方法,是程序的入口:
3     public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
4         //检查异常:
5         Class.forName("com.msb.test01.Test").newInstance();
6     }
7 }

 

throw和throws的区别

 1 package com.llh;
 2 
 3 import java.util.Scanner;
 4 
 5 
 6 public class Test7 {
 7     //这是一个main方法,是程序的入口:
 8     public static void main(String[] args) throws Exception {
 9         //实现一个功能:两个数相除,当除数为0的时候,程序出现异常。
10         /*try {
11             devide();
12         } catch (Exception e) {
13             e.printStackTrace();
14         }*/
15         devide();
16     }
17     public static void devide() throws Exception {
18         Scanner sc = new Scanner(System.in);
19         System.out.println("请录入第一个数:");
20         int num1 = sc.nextInt();
21         System.out.println("请录入第二个数:");
22         int num2 = sc.nextInt();
23         if(num2 == 0 ){//除数为0 ,制造异常。
24             //制造运行时异常:
25             /*throw new RuntimeException();*/
26             //制造检查异常:
27             /*try {
28                 throw new Exception();
29             } catch (Exception e) {
30                 e.printStackTrace();
31             }*/
32             throw new Exception();
33         }else{
34             System.out.println("商:"+num1/num2);
35         }
36     }
37 }

 

总结:

throw和throws的区别:

(1)位置不同:

throw:方法内部

throws: 方法的签名处,方法的声明处

 

(2)内容不同:

throw+异常对象(检查异常,运行时异常)

throws+异常的类型(可以多个类型,用,拼接)

 

(3)作用不同:

throw:异常出现的源头,制造异常。

throws:在方法的声明处,告诉方法的调用者,这个方法中可能会出现我声明的这些异常。然后调用者对这个异常进行处理:

要么自己处理要么再继续向外抛出异常

练习:
 1 public class Student {
 2     private String name;
 3     private int age;
 4     private String sex;
 5     public String getName() {
 6         return name;
 7     }
 8     public void setName(String name) {
 9         this.name = name;
10     }
11     public int getAge() {
12         return age;
13     }
14     public void setAge(int age) {
15         this.age = age;
16     }
17     public String getSex() {
18         return sex;
19     }
20     public void setSex(String sex) throws Exception {
21         if(sex.equals("男")||sex.equals("女")){
22             this.sex = sex;
23         }else{//非男非女
24             //解决办法1:
25             /*this.sex = "男";*/
26             //解决办法2:给个友好型提示,但是打印结果为默认的null效果
27             /*System.out.println("对不起,你的性别错误了");*/
28             //解决办法3:
29             //制造运行时异常:
30             /*throw new RuntimeException("性别不对!");*/
31             //制造检查异常
32             /*try {
33                 throw new Exception();
34             } catch (Exception e) {
35                 e.printStackTrace();
36             }*/
37             throw new Exception();
38         }
39     }
40     @Override
41     public String toString() {
42         return "Student{" +
43                 "name='" + name + '\'' +
44                 ", age=" + age +
45                 ", sex='" + sex + '\'' +
46                 '}';
47     }
48     public Student() {
49     }
50     public Student(String name, int age, String sex) {
51         this.name = name;
52         this.age = age;
53         //this.sex = sex;
54         try {
55             this.setSex(sex);
56         } catch (Exception e) {
57             e.printStackTrace();
58         }
59     }
60 }

 

 

 1 public class Test {
 2     //这是一个main方法,是程序的入口:
 3     public static void main(String[] args) {
 4         //创建一个Student的对象:
 5         /*Student s = new Student();
 6         s.setName("菲菲");
 7         s.setAge(19);
 8         try {
 9             s.setSex("asdfasdfasdf");
10         } catch (Exception e) {
11             e.printStackTrace();
12         }
13         System.out.println(s);*/
14         Student s2 = new Student("娜娜",21,"asdfasdfasdf");
15         System.out.println(s2);
16     }
17 }

 

重载和重写的异常

 

 

【1】重载:

1 public class Demo {
2     public void a() throws Exception{
3     }
4     public void a(int age) throws ArithmeticException{
5     }
6 }

 

【2】重写:

 

 

 

子类 <= 父类 

自定义异常

自定义的异常可以继承:运行时异常

 1 public class MyException extends RuntimeException {
 2     
 3     static final long serialVersionUID = -70348971907L;
 4     
 5     public MyException(){
 6     }
 7     public MyException(String msg){
 8         super(msg);
 9     }
10 }

 

也可以继承检查异常:

1 public class MyException extends Exception {
2     static final long serialVersionUID = -70348971907L;
3     public MyException(){
4     }
5     public MyException(String msg){
6         super(msg);
7     }
8 }

 

如果继承的是运行时异常,那么在使用的时候无需额外处理

如果继承的是检查异常,那么使用的时候需要try-catch捕获或者throws向上抛

 

标签:java,处理,System,catch,println,异常,public,out
From: https://www.cnblogs.com/lcs-LLH/p/17827901.html

相关文章

  • cc1: all warnings being treated as errors报错处理
    cmake时一切正常,make时产生了报错,并且解释为`cc1:allwarningsbeingtreatedaserrors`一些网上的方法是在Makefile文件里删除`-Werror`,但我的Makefile文件不存在这个选项。我的解决方法:在CMakeLists里寻找配置'-Werror'的语句,将这些涉及的语句删除。并且删除之前cmake......
  • java项目实战-spring-基本用法01-day24
    目录1.spring简单介绍2.IOC/DI--控制反转--是啥3.实现3.如果对象的属性为引用数据类型如何实例化对象4如何用注解的方式以少量的代码实现对象的创建于获取1.spring简单介绍https://spring.io什么事SSM?spring-mvcspring-framework--web服务层mybatis--......
  • 每天5道Java面试题(第10天)
    1. 自己实现一个HashMap?HashMap的实现思路:1,利用key的hashCode计算当前对象在数组中的下标。2,存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,覆盖原始值;(2)如果key不同(出现冲突),则将当前key-value放入链表中3,获取值时,直接找到对应hash值对应的下标,再进行判断key是否相同,......
  • 解决javax.persistence.RollbackException: Transaction marked as rollbackOnly Ask
    解决javax.persistence.RollbackException:TransactionmarkedasrollbackOnlyAsk在使用JavaPersistenceAPI(JPA)进行对象关系映射(ORM)的Java企业应用中,经常会遇到javax.persistence.RollbackException异常,其中的错误信息为"TransactionmarkedasrollbackOnly"。这......
  • JavaScript复习——04 事件
    事件对象事件对象是由浏览器在外面触发事件的时候创建的,这个对象封装了各种事件相关的各种信息例如:鼠标的位置键盘的按键浏览器创建事件对象后,会将事件对象作为响应参数传递在DOM类型中有多种不同类型的事件对象,但是他们都一个祖先Eventevent.clientX:获取鼠标的X轴坐标......
  • ISP图像处理Pipeline
    参考:1.键盘摄影(七)——深入理解图像信号处理器ISP2.UnderstandingISPPipeline3.ISP图像处理流程介绍4.ISP系统综述5.ISP(图像信号处理)之——图像处理概述6.ISP框架7.ISP(图像信号处理)算法概述、工作原理、架构、处理流程8.ISP全流程简介9.ISP流程介绍(Raw格式......
  • Java登陆第五天——SQL之DQL(三)
    子查询子查询就是在where中再嵌套一个查询SQL,可以理解为Java中方法的返回值。--甚至可以套中套无限套--被查询出来的表根据结果分为:单行子查询和多行子查询select列名from表名where( 另一个select语句 );准备数据--创建PersoncreatetablePerson(idint,......
  • Java中的HttpServletRequest
    Request:请求HttpServletRequest请求是获取请求行、请求头和请求体;可以通过这个方法设置防盗链,获取地址。牢记解决乱码的方式。怎么选择是重定向还是转发呢?通常情况下转发更快,而且能保持request内的对象,所以他是第一选择。但是由于在转发之后,浏览器中URL仍然指向开始页面,此......
  • 怎样用代码处理大数据量数据不会让服务器oom
    处理大数据量时,可以采取一些策略来避免服务器因内存不足而发生OOM(内存溢出)错误。以下是一些常见的处理大数据量的代码技巧和策略:分批处理数据:将大数据集分成小批次进行处理,避免一次性加载全部数据到内存中。可以使用循环迭代数据集的部分,逐步处理每个批次,并在处理完每个批次后及时......
  • Java 集合—ArrayList
    ArrayList介绍ArrayList 的底层是数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。ArrayList类位于java.util包中,使用前需要引入它,语法格式如下:importjava.util.ArrayList;//引入ArrayList类ArrayList<E>objectName=newArrayList<>();//初始化......