zoukankan      html  css  js  c++  java
  • day22_Exception

    • 异常
    • 线程

    分辨程序中异常和错误的区别

    说出异常的分类

    掌握虚拟机处理异常的方式

    列举出四个常见的运行期异常

    使用try-catch关键字处理异常

    使用throws关键字处理异常

    自定义异常类并处理之

    说出进程、线程的概念

    理解并发与并行的区别

    开启新线程

    异常

    概念:异常即不正常。和正常情况有所区别,该异常部位功能受到影响。

    程序异常指在程序运行过程中,出现非正常情况,最终会导致JVM的非正常停止。在Java等面向对象的编程语言中,异常本身就是一个类,产生异常就是创建异常对象并抛出了一个异常对象,Java处理异常的方式是:中断处理。

    备注:异常指的并不是语法错误,语法错误并不能通过编译,不会产生字节码文件,根本不能进入运行

    异常体系

    ​ 异常机制可以帮助我们找到程序中出现的问题,异常的根类是java.lang.Throwable,它的下面有两个子类:java.lang.Errorjava.lang.Exception,平常说的异常指的是 java.lang.Exception

    Throwable体系:

    • ​ Error:严重错误,无法通过异常处理解决,好比绝症,只能事先预防
    • ​ Exception:异常,异常产生后程序员可以通过适当的代码进行纠正处理,使程序能够继续进行下去,好比感冒吃药。
     * java.lang.Throwable
     * 		|-----java.lang.Error:一般不编写针对性的代码进行处理。
     *       	|-----(虚拟机错误)VirtulMachineError
     *    			|-----StackOverFlowError
     *    			|-----(内存溢出异常)OutOfMemorError
     *    		|-----AWTError
     *    		|-----LinkageError
     * 		|-----java.lang.Exception:可以进行异常的处理
     * 			|------编译时异常(checked)
     * 					|-----IOException
     * 						|-----FileNotFoundException
     * 					|-----ClassNotFoundException
     * 			|------运行时异常(unchecked,RuntimeException)
     * 					|-----NullPointerException
     * 					|-----ArrayIndexOutOfBoundsException
     * 					|-----ClassCastException
     * 					|-----NumberFormatException
     * 					|-----InputMismatchException
     * 					|-----ArithmeticException
     *    				|-----NoSuchElementExceprion
     *    		|-----SQLException
    

    异常的处理

    ​ Java异常处理的五个关键字:try catch finally throw throws

    抛出异常throw

    ​ 当我们在编写程序的时候,我们必须考虑程序可能出现的问题,比如说:在定义方法的时候,方法需要接收参数、对于调用者来说,当调用方法的时候需要接收参数,首先需要对参数数据进行合法的判断,若数据不合法,就应该告诉调用者,传递合法的数据进来。这时候就需要使用抛出异常的方式来告诉调用者。

    在Java当中,提供了一个关键字throw,用来抛出一个指定的异常对象。操作步骤:

    1. ​ 创建一个异常对象,封装提示信息
    2. ​ 需要将这个异常对象告知给调用者,通过关键字throw就可以完成。throw抛出一个异常对象

    ​ 备注:throw一般用在方法内,用来抛出一个具体的异常对象,将这个异常对象抛出给调用者处并结束当前方法的执行

    使用格式:

    throw new 异常类名 (参数)
    示例:
        //给调用者抛出一个空指针异常
        throw new NullPointException("要访问的数组索引不存在");
    	//索引越界
    	throw new IndexOutOfBoundException("该索引超出引用范围");
    

    Objects非空判断

    ​ 在该类中,提供了一些静态的实用方法,这些方法是null-safe(空指针安全)或者null-tolerant(容忍空指针的),在源码当中,对对象的null值进行了抛出异常的操作。

    ​ public static T requireNonNull(T obj):查看指定的引用对象不是null值

    public static <T> T requireNonNull(T obj) {
            if (obj == null)
                throw new NullPointerException();
            return obj;
        }
    

    声明异常处理throws

    声明异常:将问题标识出来、报告给调用者,如果方法内通过throw抛出了一个编译期异常,又没有通过捕获处理异常,那么必须通过throws进行声明,让调用者处理。

    关键字throws运用在方法的声明上,用于表示当前方法不处理异常,提醒调用者处理该异常(该方法携带异常)。

    声明异常处理的格式:

    修饰符  返回值类型  方法名(参数列表) throws XxxException1,XxxException2,...{//或多个异常种类
    }
    示例:
        public class ThrowsDemo{
         	public static void main(String []args){
                read("C:/a.txt");
            }   
            public static void read(String path) throws FileNotFoundException{
                //校验  如果传递的路径不是以.txt结尾的,抛给调用者文件找不到异常
                if(!path.endsWith(".txt")){
                    //抛出文件找不到异常
                    throw new FileNotFoundException("文件找不到");
                }
            }
        }
    

    捕获异常try-catch

    如果异常出现的话,会立刻终止程序

    ​ 处理方式:

    ​ 1.如果使用throws关键字来声明式处理,相当于没有处理。异常交给方法的调用者

    ​ 2.在方法中使用try-catch语句块处理异常

    try-catch的方式就是捕获异常

    • 捕获异常:Java中对异常有针对性的语句块来进行捕获,可以对出现的异常进行指定的方式处理

    格式:

    try{
    	//可能会出现异常的代码
    } catch (异常类型 e){
        //处理异常的逻辑代码
        //记录日志  //打印异常信息  //继续向上抛(不建议)
    }
    

    try:该语句块中可能出现异常的代码

    catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理

    备注:try 和 catch都不能单独使用,一般建议连用

    public class TryCatchDemo{
        public static void main(String []args){
            try{
                readFile("D:\a.txt");  
            }catch(FileNotFoundException e){//try中抛出的是什么异常类型,在括号中就定义什么异常类型
                //打印异常信息
                System.out.print(e);
            }
            
        }
        public static void readFile(String path) throws FileNotFoundException{
            if(!path.startsWith("C:")){
                throw new FileNotFoundException("文件找不到");
            }
        }
    }
    

    如何获取异常的信息

    ​ Throwable类中定义了一些常用的API方法

    • ​ public String getMessage():获取异常的描述信息和原因(提示给用户错误原因)

    • ​ public String toString():获取异常的类型、异常的描述信息

    • ​ public void printStackTrace():打印异常的跟踪栈信息并且输出到控制台中

      ​ 包含了异常的类型、异常的原因、还包括异常出现的位置,在开发和调试阶段,一般都使用printStackTrace方法

    finally语句块

    finally:有一些特定的代码,无论异常是否发生,都需要执行,当程序发生异常时,会引发程序的跳跃性,导致有一些代码加载不到,而finally语句块就是用来解决这样的问题的,在finally语句块中存放的代码一般都是一定会被执行到的

    什么样的代码最终一定要被执行?

    ​ 比如:在try中打开了一些物理资源(磁盘文件、网络连接、数据库的连接),我们一般在使用完毕后必须关闭掉,可以使用finally语句块来实现。

    finally语句块的语法格式:

    try{
        // ...
    }catch(异常类型 e){
        // ...
    }...
    finally{
        //  ...
    }
    

    备注:中间的catch语句块可以省略,finally不能单独使用。建议连用

    public class FinallyDemo01{
        public static void main(String []args){
            try{
                readFile("D:\a.txt");  
            }catch(FileNotFoundException e){//try中抛出的是什么异常类型,在括号中就定义什么异常类型
                //打印异常信息
                System.out.print(e);
            }
            finally{
                System.out.println("不管程序如何运行,此行代码一定被加载");
                System.out.println("此处可以进行资源关闭");
            }
        }
        
         public static void readFile(String path) throws FileNotFoundException{
            if(!path.startsWith("C:")){
                throw new FileNotFoundException("文件找不到");
            }
        }
    }
    

    备注:

    ​ 1.如果finally语句块中有return语句,永远返回的是finally语句块中的结果值

    ​ 2.当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会被执行到,否则finally永远被执行

    异常的注意事项

    ​ 当程序中出现了多个异常,那么又该如何捕获和处理呢?

    1. ​ 多个异常,分别处理
    2. ​ 多个异常一次捕获、多次处理
    3. ​ 多个异常一次捕获、一次处理

    一般我们都是使用一次捕获、多次处理的方式

    try {
        //可能出现异常的代码  多个异常
    } catch (异常类型A e){ //当try中出现A异常的时候,用改catch来捕获
        //处理异常的逻辑 
    }catch (异常类型B e){ //当try中出现B异常的时候,用改catch来捕获
        //处理异常的逻辑
    }catch (异常类型C e){ //当try中出现C异常的时候,用改catch来捕获
        //处理异常的逻辑
    }
    ...
    

    注意:这种异常处理方式,要求多个catch的异常不能相同,并且若catch中的多个异常之间存在子父类关系,那么子类异常的处理要求在父类异常处理的上面,父类异常的处理在下面

    子父重写时异常:

    • ​ 运行时异常被抛出可以不处理,即不捕获也不声明
    • ​ 如果finally中有return语句,那么永远返回finally语句块中的结果值
    • ​ 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者父类异常的子类或者不抛出异常
    • ​ 父类方法如果没有抛出异常,子类重写该方法时也不可能抛出异常。此时子类方法内产生了异常,只能捕获处理,不可声明抛出

    自定义异常

    Java中根据不同的情况提供了不同的异常类,JDK官方提供的异常类始终是有限的,大多数情况下我们需要根据自己的业务需要来定义异常类,例如:年龄负数异常、成绩负数异常、登陆异常等等

    什么是自定义异常类?

    ​ 在开发中,根据自己业务的异常情况来定义异常类。

    ​ 例如:自定义一个业务逻辑异常类: 注册异常 RegisterException

    异常类定义的两种方式:

    1. ​ 自定义一个编译期异常类,自定义类继承于 java.lang.Exception
    2. ​ 自定义运行期异常类,继承于 java.lang.RuntimeException
    //首先定义一个注册异常类 RegisterException   
    public class RegisterException  extends  RuntimeException{
        //空参构造
        public RegisterException (){
        }
        //有参构造
        public RegisterException (String message){
            super(message);
        }
    }
    
    public class Demo{
        //使用数组模拟数据库 已存在多个账户名称
        public static String[] names = {"校长","小王"};
        
        public static void main(String []args){
            String name = new Scanner(System.in).next();
            //校验账户是否出现异常
            try{
                checkName(name);
                System.out.println("注册成功!!!");
                names = Arrays.copyOf(name,names.length+1);
                names[names.length-1] = name;
            }catch(){
                e.printStackExceptionn;
            }
        }
        
     public static boolean checkName(String userName) throws RigisterException{
         for(String name : names){
             if(name.equals(userName)){
                 throw new RigisterException("你的名字已经被注册过了");
             }
         }
     }
    }
    
  • 相关阅读:
    物理好题随想
    学案12:电场强度和静电现象
    vscode插件记录
    windows使用总结
    元素周期律 + 元素周期表
    酸碱理论
    氮族元素——磷
    氮族元素——氮
    碱金属元素
    SDN第一次上机实验
  • 原文地址:https://www.cnblogs.com/mitoris/p/14106215.html
Copyright © 2011-2022 走看看