【Java】认识异常

文章详细介绍了Java中的异常处理,包括异常的概念和分类,如Error和Exception,异常的抛出和捕获机制,如try-catch和throws的使用,finally块在资源清理中的作用,以及如何自定义异常类。文章强调了编译时异常和运行时异常的区别,并提供了示例代码进行说明。
摘要由CSDN通过智能技术生成

目录

1.异常概念和分类

2.异常的抛出 

3.异常的捕获

3.1异常声明throws

3.2异常捕获try-catch

3.3finally

3.4.异常的处理流程

4.自定义异常类 


1.异常概念和分类

public class Test {
    public static void test() {
        test();
    }
    public static void main(String[] args) {
        System.out.println(10/0);//ArithmeticException
        int[] arr = null;
        System.out.println(arr.length);//NullPointerException
        test();//StackOverflowError
    }
}

定义:程序执行过程中发生的不正常行为称为异常。

分类:Throwable (异常体系的顶层类):Error (错误)、Exception (异常):受查异常/编译时期异常、非运行异常/运行时异常。

 

2.异常的抛出 

定义:使用 throw 关键字,抛出一个指定的异常对象,将错误信息告知给调用者。

格式:throw new XXXException (“异常产生的原因”);

public class Test {
   public static void main(String[] args) {
       int a = 0;
       if (a == 0) {
           throw new ArithmeticException("分母不能为零");
       }
       System.out.println(10/0);//不会执行
   }
}

注意:1> throw必须写在方法体内部;

2> 如果抛出的是RunTimeException其子类对象,即运行时异常,可不用处理,交给JVM即可;

3> 如果抛出的是Exception及其子类对象,即编译时异常,就必须由用户处理,否则无法通过编译;

4> 异常一旦抛出,其后的代码就不会执行。

3.异常的捕获

3.1异常声明throws

定义:在方法声明时参数列表后,当方法中抛出编译时异常,而用户自己不想处理该异常,此时就可以将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常

注意:1> throws必须跟在方法的参数列表之后;

2> 声明的异常必须是Exception或Exception的子类;

3> RunTimeException及其子类的异常不需要声明,交给JVM即可;

4> 如果方法内部抛出多个异常,throws后需跟多个异常类型,之间用逗号隔开;

5> 如果多个异常具有父子类关系,只声明父类即可。

import java.io.FileNotFoundException;
import java.io.IOException;

class Student implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {//抛出异常
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        student.clone();//不抛出异常此行代码会报错
    }
    public static void main3(String[] args) throws IOException, FileNotFoundException { 
                                                 //FileNotFoundException是IOException的子类,
                                                 //只用写IOException即可
    }
}

3.2异常捕获try-catch

import java.io.FileNotFoundException;
import java.io.IOException;

class Student { //此时不支持克隆
    @Override
    protected Object clone() throws CloneNotSupportedException {//抛出异常
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Student student = new Student();
        try { //将可能出现异常的代码放在这里面
            student.clone();
            int[] arr = null;
            System.out.println(arr.length);//这里也有异常,但不会被捕获,先到先得
            System.out.println("abc");//若上面抛出了异常,这行代码不会执行
        } catch (CloneNotSupportedException e) { //可能捕获的异常
            e.printStackTrace();//打印异常所在的行数
            throw new RuntimeException(e); //捕获到异常则执行这里面的代码 --- *
        }catch (NullPointerException e) {//若上面已经捕捉到了异常,这里就捕获不了了
            e.printStackTrace();         //即无法同时捕捉多个异常
            throw new NullPointerException();
        }
        catch (ArithmeticException | IndexOutOfBoundsException e) {
            e.printStackTrace();
            System.out.println("Exception"); //不建议这样写,因为此时无法准确判断是什么异常
        }
        catch (Exception e) { //最后一道保险,防止还有异常没有捕获
            throw new Exception();//先捕捉子类异常,再捕捉父类异常
        }
        System.out.println("abcd");//若*行是处理异常,剩下程序不会执行
                                   //若*行只是声明捕获到了异常,剩下程序会继续执行
    }
}

3.3finally

有些特定的代码,不论程序是否正常运行,都需要执行,比如程序中打开的资源在程序结束时需要关闭或回收。此时就需要finally来解决资源清扫的扫尾工作。 

import java.util.InputMismatchException;
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
            int a = scanner.nextInt();
            int ret = 10/a;
            System.out.println("ret的值是"+ret);
            //return 1; //若这里是方法,return后finally仍然会执行
        }catch (ArithmeticException e) {
            System.out.println("捕获到了ArithmeticException异常");
        }catch (InputMismatchException e) {
            System.out.println("输入的参数类型有误");
        }finally { //一定执行
            scanner.close();//关闭Scanner
            System.out.println("finally被执行了");
            //return 1; //当try和finally中都有return时,取finally中的return
        }               //不建议在finally中写return
        System.out.println("ttr-catch-finally之后的代码");
    }
}

3.4.异常的处理流程

在方法的调用过程当中,当被调用的方法没有处理异常,会沿着栈把这个异常抛给它的调用者,当调用者也没有处理时,就会抛给JVM,程序会异常终止。

4.自定义异常类 

在没学异常之前,我们的代码是这样的:

class Login {
    private String userName = "admin";
    private String password = "12345678";
    public void loginInfo(String userName,String password) {
        if (!this.userName.equals(userName)) {
            System.out.println("用户名错误");
            return;
        }if (!this.password.equals(password)) {
            System.out.println("密码错误");
            return;
        }
        System.out.println("登陆成功");
    }
}
public class Test {
    public static void main(String[] args) {
        Login login = new Login();
        login.loginInfo("adminabc","12345678");//用户名错误
    }
}

学了异常后,我们就可以自定义异常类了:

注意:1> 继承于Exception (编译时异常/受查异常) 或RunTimeException (运行时异常/非受查异常),继承哪个根据业务需求;

2> 最好实现一个带有String类型参数的构造方法,参数含义是出现异常的原因,这样代码更具有可读性,出错时更好定位。

public class UserNameException extends RuntimeException{ //不继承就不是异常
                                       //这是运行时异常,可不处理
    public UserNameException(String message) {
        super(message);
    }
}
public class PasswordException extends Exception{ //不继承就不是异常
                                       //这是编译时异常,必须要处理
    public PasswordException(String message) {
        super(message);
    }
}
class Login {
    private String userName = "admin";
    private String password = "12345678";
    public void loginInfo(String userName,String password) throws PasswordException{ //编译时异常必须处理
        if (!this.userName.equals(userName)) {
            throw new UserNameException(userName+" 用户名错误");
        }if (!this.password.equals(password)) {
            throw new PasswordException(password+" 密码错误");
        }
        System.out.println("登陆成功");
    }
}
public class Test1 {
    public static void main(String[] args) {
        Login login = new Login();
        try {
            login.loginInfo("adminabc", "12345678");//用户名错误
        }catch (PasswordException e) { //编译时异常必须处理
            e.printStackTrace();
        }
    }
}

JavaSE终于结束啦!!!!!!

数据结构我来啦!!!!! 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值