• Java 异常处理


    异常处理

    我们有很多问题不是靠代码能够避免的,比如客户输入数据的格式,读取文件是否存在,网络是否保持通畅等

    异常:在JAVA语言中,将程序执行中发生的不正常情况成为异常(语法错误和逻辑错误不是异常)

    Java发现的异常可分为两类:
    在这里插入图片描述
    在这里插入图片描述

    java.lang.Throwable

    1.java.lang.Error:一般不编写针对性的代码进行处理
    2.java.lang.Exception:

    分为两类:
    编译时异常(checked)

    • IOException
    • FileNotFoundException
    • ClassNotFoundException

      运行时异常(unchecked)
    • NullPointerException
    • ArrayIndexOutOfBoundsException
    • ClassCastException
    • NumberFormatException
    • InputMismatchException
    • ArithmaticException

    一些异常代码如下

    package baozhuang;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.sql.Date;
    import java.util.Scanner;
    
    import org.junit.Test;
    
    public class ExceptionTest {
    	
    	// NullPointerException 空指针
    	@Test
    	public void test1(){
    		int[] arr = null;
    		System.out.println(arr[3]);
    	}		
    	
    	// ArrayIndexOutOfBoundsException  数组角标越界
    	@Test
    	public void test2(){
    		int[] arr = new int[10];
    		System.out.println(arr[10]);
    	}
    
    	//ClassCastException 类型转换异常
    	@Test
    	public void test3(){
    		Object obj = new Date(0);
    		String str = (String)obj;
    	}
    
    	// NumberFormatException 
    	@Test
    	public void test4(){
    		String str = "123";
    		str = "abc";
    		int num = Integer.parseInt(str);
    	
    	}
    
    	// InputMismatchException  输入不匹配
    	@Test
    	public void test5(){
    		Scanner scanner = new Scanner(System.in);
    		int score = scanner.nextInt(); //输入abc
    		System.out.println(score);
    	}
    
    	// ArithmaticException 算数异常
    	@Test
    	public void test6(){
    		int a = 10;
    		int b = 0;
    		System.out.println(a/b);
    	}
    
    
    	// ***********************以下是编译异常****************************************
    	// 会在旁边打叉叉
    	@Test 
    	public void test7(){
    		File file = new File("hello.txt");
    		FileInputStream fis = new FileInputStream(file);
    		int data = fis.read();
    		while (data != -1){
    			System.out.println((char)data);
    			data = fis.read();
    		}
    	
    		fis.close();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    异常处理方式

    在这里插入图片描述

    异常的处理:抓抛模型

    过程一: “抛” : 一旦出现异常,就会在异常代码处生成一个对应异常类的对象。
    并将此对象抛出,一旦抛出对象以后,其后的代码就不再执行

    过程二:“抓” : 可以理解为异常的处理方式 : try - catch - finally ,throws

    方式一:try - catch - finally

    try{
    // 可能出现异常的代码
    }catch(异常类型1 变量名1){
    // 处理异常方式1
    }catch(异常类型2 变量名2){
    // 处理异常方式2
    }catch(异常类型3 变量名3){
    // 处理异常方式3
    }

    finally{
    //一定会执行的代码
    }

    • 使用try将可能出现异常的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配

    • 一旦try中的异常对象匹配到某一个catch时,就会进入catch中进行异常的处理,一旦处理完成,就会跳出try-catch结构(在没有写finally的情况下),继续执行其后的代码

    • 异常处理catch要求有子父类关系,子类要在父类上面

    • 常用异常处理对象如下 String getMessage 2. printStackTrace

    • 在try结构中声明的变量,出了try结构以后,就不能再被调用

      package baozhuang;

      import org.junit.Test;

      public class ExceptionTest1 {

        @Test
        public void test1(){
        
        	String str = "123";
        	str = "abc";
        
        	try{
        		int num = Integer.parseInt(str);
        		System.out.println("hello--------1");  // 无法执行
        	}catch(NumberFormatException e){
        		//System.out.println("出现数值转换异常了,不要着急....");
        		// 常用异常处理对象如下 String getMessage  2. printStackTrace
        		//System.out.println(e.getMessage());  
        		e.printStackTrace();
        	}
        
        	System.out.println("hello--------2"); // 可以执行
        }
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    finally是可以选的

    finally中声明的是一定会被执行的代码,即使catch又出现异常了,或者try中有return语句,catch中有return语句的情况

    像数据库连接、输入输出流、网络编程Stock等资源、JVM是不能自动回收的,我们需要自己进行手动资源的释放,这需要声明在finally中

    一个小例子
    package baozhuang;
    
    import org.junit.Test;
    
    public class finallyTest {
    	@Test
    	public void test1(){
    		try{
    			int a = 10;
    			int b = 0;
    			System.out.println(a/b);
    		}catch(ArithmeticException e){
    			//e.printStackTrace();
    			int[] arr = new int[10];
    			System.out.println(arr[10]); // 异常
    		}catch(Exception e){
    			e.printStackTrace();
    		}finally{
    			System.out.println("我好帅"); // 照样执行
    		}
    		System.out.println("我好帅222");  // 不执行
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    体会1: 使用try - catch - finally 处理编译时异常,使得程序在编译时不再报错,但仍有可能在运行时报错。相当于将编译时可能出现的异常延迟到运行时出现
    体会2:由于运行时异常比较常见,我们通常不针对运行时异常编写try - catch ,通常对编译时异常进行处理

    方式二:throws + 异常类型

    • throws + 异常类型 写在方法声明时,指明此方法执行时,可能会抛出的异常类型,一旦方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此异常是thorws 后异常类型时,则会被抛出。异常代码后续的代码就不再执行

    体会:try - catch - finally 真正的将异常给处理了。throws 的方式只是将异常抛给了方法的调用者,并没有将异常处理掉

    子类重写的规则之一:子类重写的方法抛出的异常类型不大于被重写方法抛出的异常类型
    package baozhuang;
    
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class OverrideTest {
    	public static void main(String[] args) {
    		OverrideTest test = new OverrideTest();
    		test.display(new SubClass());
    	}
    
    	public void display(SuperClass s){
    		try{
    			s.method();
    		}catch(IOException e){
    			e.printStackTrace();
    		}
    	}
    
    }
    
    class SuperClass{
    	public void method() throws IOException{
    	
    	}
    }
    
    
    class SubClass extends SuperClass{
    	public void method() throws FileNotFoundException{
    	
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    开发中如何选择 try - catch - finally 还是用throws

    • 如果父类中被重写的方法没有throws方式异常处理,则子类重写的方法也不能使用throws , 意味着如果子类重写的方法中有异常,必须用try - catch - finally
    • 执行方法a中,先后调用了另外几个方法,这几个方法是递进关系的,我们建议这几个方法用throws方法进行处理,而执行的方法a可以考虑用try - catch -finally 进行处理

    关于异常对象的产生,我们可以手动的生成一个异常对象,并抛出(throw)

     package baozhuang;
    
    public class StudentTest {
    	public static void main(String[] args) {
    		try {
    			Student s = new Student();
    			s.regist(-1001);
    			System.out.println(s);
    		} catch (Exception e) {
    			// e.printStackTrace();
    			System.out.println(e.getMessage());
    		}
    
    	}
    }
    
    class Student{
    	private int id;
    
    	public void regist(int id) throws Exception{
    		if (id > 0){
    			this.id = id;
    		}else{
    			//System.out.println("输入的id违法");
    			// 手动抛出异常对象
    			//throw new RuntimeException("您输入的数据违法!");
    			throw new Exception("您输入的数据违法!");
    		}
    	}
    
    	@Override
    	public String toString() {
    		return "Student [id=" + id + "]";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    如何自定义异常类?

    1.需要去继承现有的异常类,例如RuntimeException,Exception
    2. 提供seriaVersionUID
    3. 提供重载的构造器

    package baozhuang;
    
    public class MyException extends RuntimeException {
    	static final long seriaVersionUID = -7034897190745766939L;
    	public MyException(){
    	
    	}
    
    	public MyException(String msg){
    		super(msg);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    【力客热题HOT100】-【068】238 除自身以外数组的乘积
    麒麟arm操作系统自动部署x11vnc,非交互改密
    [附源码]java毕业设计高校创新创业项目管理系统
    JMETER前置处理器类型
    电子学会C/C++编程等级考试2022年06月(一级)真题解析
    R语言ggplot2可视化:使用ggplot2可视化散点图、使用scale_color_viridis_d函数指定数据点的配色方案
    第六章 解析glob.glob与os.walk(工具)
    计算机毕业设计ssm+vue基本微信小程序的高速公路服务区充电桩在线预订系统 uniapp 小程序
    cache存储器最全详细介绍
    涨姿势了,殊途同归的图片交互动效制作!
  • 原文地址:https://blog.csdn.net/abc1234564546/article/details/127618076