JAVA中的异常处理

 

一、定义

程序执行过程中的不正常行为称为异常。

二、异常的体系结构

6578fbc632d7438885d43c1611e46f6d.png

1.Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception
2. Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表:StackOverflowError和OutOfMemoryError,一旦发生回力乏术,需要程序员来修正。
3. Exception:异常产生后程序员可以通过代码进行处理,也可以由JVM处理,使程序继续执行。

三、异常的分类

1.编译时异常(受检查异常)

2.运行时异常(非受检查异常):有RunTimeException

注解:语法错误(拼写出错)不是异常,而是拼写错误

在Java中,标识符是用来命名变量、方法、类等的名称。标识符必顮要遵守以下规则:

  1. 必须以字母、下划线(_)或者美元符($)开头
  2. 其他部分可以是字母、数字、下划线(_)或者美元符($)
  3. 大小写敏感

根据这些规则,"system" 是一个合法的标识符,与大小写有区别。因此,在Java中,"system" 和 "System" 被视为不同的标识符。因此,如果你将 "System" 错误地拼写为 "system",编译器会将其视为另一个不同的标识符,可能导致意外的行为或错误。

四、异常处理的方法

分类

1.防御式编程:LBYL形处理:把正常流程与错误流程混在一起处理,比如if(){}else(){}混用。

2.事后认错形处理:EAFP:try{}catch{}finally{}

使用方法

依靠五个关键字:throw,throws,try,catch,final

一、抛出异常(throw)

1.throw必须写在方法体内部
2. 抛出的对象必须是Exception 或者 Exception 的子类对象
3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
5. 异常一旦抛出,其后的代码就不会执行

二、捕获异常(1.异常声明throws    2.捕获处理try,catch)

1.处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。

2.处理:

try{}花括号内写可能发生异常的语句,catch(异常类型 变量名){处理},finally{}里面的代码不管有无异常都会执行,根据这个特性可以进行文件关闭等操作。

注解:

1. try块内抛出异常位置之后的代码将不会被执行
2. 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到JVM收到后中断程序----异常是按照类型来捕获的

3. try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获----即多种异常,多次捕获

如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则语法错误:

 可以通过一个catch捕获所有的异常,即多个异常,一次捕获(不推荐)

由于 Exception 类是所有异常类的父类. 因此可以用这个类型表示捕捉所有异常.

 

自定义异常(以及实战代码)

import java.util.Scanner;

class userNameException extends Exception{
     public userNameException(String message){
         super(message);
     }
}
class userPasswordException extends Exception{
     public userPasswordException(String message){
         super(message);
     }
}
public class user {
    private static String name="admin";
    private static String password="123";

    public static void login()throws userNameException, userPasswordException{
         Scanner p=new Scanner(System.in);
         String name1=p.nextLine();
         String password1=p.nextLine();
        if(!name.equals(name1)){
            throw new userNameException("用户名异常。。。。");
        }
        if(!password.equals(password1)) {
            throw new userPasswordException("密码异常。。。。");
        }
    }

    public static void main(String[] args) {
        while(true){
            try{
                login();
                System.out.println("登录成功");
               break;
            }catch(userNameException e){
                e.printStackTrace();
                System.out.println("用户名异常,请重新输入");
               continue;
            }catch(userPasswordException e){
                e.printStackTrace();
                System.out.println("密码异常,请重新输入");
                continue;
            }finally {
                System.out.println("。。。。。。。");
            }

        }

    }
}

需要注意的点:

1.写的是自定义的子类,表示自定义的类型错误,需要继承父类的Exception方法,而子类调用父类,父类有构造方法时,需要使用super来访问父类构造方法。

在Java中,异常类的构造方法通常会接受一个字符串参数,这个字符串参数就是用来描述异常情况的信息。当在抛出异常时使用throw new ExceptionType("message")语句时,其中的"message"会被传递给异常类的构造方法,然后在异常对象被创建时,这个字符串信息就会被存储在异常对象中。

当异常被捕获和处理时,可以通过异常对象的getMessage()方法来获取这个字符串信息,并据此进行相应的处理。因此,在自定义异常类时,通过构造方法传入字符串参数,可以使得在抛出异常时能够携带相关的描述信息,方便在异常被捕获后理解异常的原因。

2.login方法中没有处理异常,要使用throws关键字抛出异常,给调用的函数处理

3.catch的参数,一定要写类型名+变量名,不能只写一个类型名

 

下面,来讲讲我在写这份代码时遇到的问题,以下是初始代码:

import java.util.Scanner;

class userNameException extends Exception{
     public userNameException(String message){
         super(message);
     }
}
class userPasswordException extends Exception{
     public userPasswordException(String message){
         super(message);
     }
}
public class user {
    private static String name="admin";
    private static String password="123";
    static Scanner p=new Scanner(System.in);
    static String name1=p.nextLine();
    static String password1=p.nextLine();

    public static String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Scanner getP() {
        return p;
    }

    public void setP(Scanner p) {
        this.p = p;
    }

    public static String getName1() {
        return name1;
    }

    public void setName1(String name1) {
        this.name1 = name1;
    }

    public static String getPassword1() {
        return password1;
    }

    public void setPassword1(String password1) {
        this.password1 = password1;
    }

    public static void login()throws userNameException, userPasswordException{
        String name1=getName1();String name=getName();
        String password1=getPassword1();String password=getPassword();
        if(!name.equals(name1)){
            throw new userNameException("用户名异常。。。。");
        }
        if(!password.equals(password1)) {
            throw new userPasswordException("密码异常。。。。");
        }
    }

    public static void main(String[] args) {
        while(true){
            try{
                login();
                System.out.println("登录成功");
               break;
            }catch(userNameException e){
                e.printStackTrace();
                System.out.println("用户名异常,请重新输入");
               continue;
            }catch(userPasswordException e){
                e.printStackTrace();
                System.out.println("密码异常,请重新输入");
                continue;
            }finally {
                System.out.println("。。。。。。。");
            }

        }

    }
}

一开始,输入正确的用户名和密码可以正常登录,但是输入错误的就死循环了,这是因为,尽管重新调用login,却没有重新赋值,因此死循环

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值