ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

异常和线程

2020-12-11 23:01:45  阅读:123  来源: 互联网

标签:抛出 throw try 线程 catch 异常 public


本章内容

  • 异常
  • 线程

异常

异常的概念

​ 异常:不正常,有毛病。程序当中的异常指的是出现的不正常的情况,会导致JVM的非正常停止。

在java等面向对象的编程中,异常本身就是一个类。产生异常就是创建异常对象,并且抛出了一个异常对象。JAVA处理异常的方式很粗暴,直接中断处理。

备注:指的并不是语法错误,如果语法错误,编译无法通过,不会产生字节码文件,根本不会在JVM中运行

异常体系

异常机制其实是帮助我们找到程序中出现的问题,异常的根类是java.lang.Throwable。它的下面有两个子类,一个是java.lang.Error 和java.lang.Exception,平常说的异常是java.lang.Exception

Throwable体系
在这里插入图片描述

  • Error:严重错误,无法通过,好比绝症,只能事先预防

  • Exception:异常,异常产生后程序员可以通过代码的方式进行纠正处理,使程序能够继续进行下去。好比感冒,可以吃药,
    在这里插入图片描述

异常的处理:

java处理异常的关键字:try catch finally throw throws

抛出异常throw

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

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

1、创建一个异常对象,封装一些提示信息

2、需要将这个异常对象告知给调用者,通过关键字throw就可以完成,throw抛出一个异常对象

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

使用格式:

throw new 异常类名(参数)

示例:

//给调用者抛出一个空指针异常
throw new NullPointerException("要访问的arr数组不存在,值为null");
    
  //索引越界异常
    throw new IndexOutOfBoundsException("该索引超出引用范围");

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抛出一个编译期异常,又没有通过捕获处理(try…catch),那么必须通过throws进行声明,让调用者处理

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

格式:

修饰符 返回值类型 方法名(参数列表) throws 异常类名1,异常类名2....{}
public class DemoThrows throws FileNotFoundException{
    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){
        //处理异常的逻辑代码
        //1.记录日志
        //2.打印异常信息
        //3.继续往上抛
    }
    

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

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

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

public class TryCatchDemo{
    
    public static void main(String []args){
        try{
             readFile("D:");
        }catch(FileNotFoundException e){//括号中需要定义异常类型
            //try中抛出的是什么类型,在括号中就定义成什么异常类型
            //打印异常信息
            System.out.println(e);
        }
          System.out.println("程序往下加载");
       
    }
    public static void readFile(String path) throws FileNotFoundException{
        if(!path.startWith("C:")){
            throw new FileNotFoundException("传递的文件不再C盘,文件找不到");
        }
    }
    
}

如何获取异常的信息

Throwbale类中定义了一些常用的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 Finally{
    
    public static void main(String []args){
        try{
            System.out.println("开启IO流");
            readFile("b.txt");
    }catch (IOException e){
            e.printStackTrace();
        }
        finally{
             System.out.println("关闭IO流");
        }
        System.out.println("Over");
 
        
    }
       public static void readFile(String path) throws IOException{
        if(!path.endsWith(".txt")){
            throw new IOException("文件的后缀名不正确");
        }
    
}

备注

1.如果finally语句块中有return,永远返回fianlly语句块中的内容

2.当只有在try中或者catch中调用退出虚拟机的情况下,finally才不会被执行到,否则永远会被执行

异常的注意事项

当程序中出现了多个异常该如何捕获、处理

1.多个异常分别处理

2.多个异常一次捕获,多次处理

3.多个异常一次捕获,一次处理

一般我们都是使用一次捕获,多次处理

try{
    //可能出现异常的代码
}catch(异常类型A e){
    //处理异常逻辑
}catch(异常类型B e){
    //处理异常逻辑
}
...
    ...

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

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

自定义异常

概述:

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

什么是自定义异常类?

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

我想自定义一个业务逻辑异常:注册异常

如何定义?

  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){
        Scanner sc=new Scanner(System.in);
        String name=sc.next();   
        //校验账户是否已被注册
        try{
            checkName(name);
            System.out.println("注册成功");
        }catch( RegisterException e){
            //异常的处理逻辑
            e.printSteakTrace();       
        }
       

    }
    public static boolean checkName(String username) throws RegisterException {
        for(String name:names){
            if(name.equals(username)){
                //表明名字已经注册过了,就跑出注册异常
                throw new RegisterException("名字已被注册");
            }
        }
        return true;
    }
    
}

标签:抛出,throw,try,线程,catch,异常,public
来源: https://blog.csdn.net/zwh19990526/article/details/111054891

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有