Java入门系列-20-异常

为什么要进行异常处理

下面这段代码能否正常执行

public class DemoCalc {
    public static void main(String[] args) {
        int a=0;
        int b=0;
        int c=a/b;
        System.out.println("运算结果为:"+c);
    }
}

结果是我们在控制台中看到一段错误提示,那是因为除数不能为0。异常就是在程序运行过程中发生的不正常事件,会中断运行的程序

Java 使用了异常处理机制为程序提供了错误处理的能力,在程序中预先设置好对付异常的处理办法,待程序发生异常时对异常进行处理,处理完毕后,程序便可以继续运行。

下面来看一下Java中是如何进行异常处理的

如何进行异常处理

Java 的异常处理是通过5个关键字实现的:try、catch、finally、throw、throws

关键字 作用
try 执行可能产生异常的代码
catch 捕获异常
finally 无论是否发生异常,代码总能执行
throws 声明方法要抛出的异常
throw 手动抛出异常

常见异常及异常分类

Throwable 是Java 中所有错误和异常的父类

Error类:Throwable的子类,仅靠程序本身无法恢复的严重的错误。

Exception类:Throwable的子类,由Java应用程序抛出和处理的非严重错误

RuntimeException类:Exception的子类,运行时异常,不要求程序必须做出处理。

Checked异常:Exception的子类,程序必须处理该类异常。

常见异常类型

异常类型 说明
Exception 异常层次结构的父类
ArithmeticException 算数错误情形,如以零作除数
ArrayIndexOutOfBoundsException 数组下标越界
NullPointerException 尝试访问null对象成员
ClassNotFoundException 不能加载所需的类
IllegalArgumentException 方法接收到非法参数
ClassCastException 对象强制类型转换出错
NumberFormatException 数字格式转换异常,如把"abc"转换成数字

try-catch

语法:

public void method(){
    try{
        //代码段1
        //可能产生异常的代码段
        //代码段2
    }catch(异常类型 ex){
        //对异常进行处理的代码段
    }
    //代码段
}

try-catch块捕获异常有三种情况:

1、try块中没有任何异常,try中正常,catch不会执行,正常执行try-catch后的代码。

2、try块中可能发生异常的代码段发生异常,代码段2不会执行,而是执行catch中异常处理的代码,正常执行try-catch后的代码。

catch中异常类型的printStackTrace() 方法能进行堆栈跟踪显示出程序运行到当前类的执行流程,异常堆栈信息中包含了异常的类型及异常出现的位置。

3、异常类型不匹配,程序将中断。比如try产生的异常为ArithmeticException,catch却用了 ClassCastException。

在控制台中接收数字做除法运算

import java.util.Scanner;

public class DemoInput {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try{
            System.out.println("请输入被除数(整数):");
            int a=input.nextInt();
            System.out.println("请输入除数(整数):");
            int b=input.nextInt();
            int c=a/b;
            System.out.println("结果:"+c);
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("程序结束");
    }
}

try-catch-finally

语法:

public void method(){
    try{
        //可能会发生异常的代码
    }catch(异常类型 ex){
        //异常处理
    }finally{
        //无论如何都要执行的代码
    }
}

finally块:是否发生异常都执行

finllay块不执行的唯一情况:之前的代码中执行了 System.exit(1); 退出虚拟机

try-catch-finally的使用

import java.io.FileNotFoundException;
import java.util.Scanner;

public class DemoInput {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try{
            System.out.println("请输入被除数(整数):");
            int a=input.nextInt();
            System.out.println("请输入除数(整数):");
            int b=input.nextInt();
            int c=a/b;
            System.out.println("结果:"+c);
        }catch(Exception ex) {
            ex.printStackTrace();
        }finally {
            System.out.println("感谢您的使用");
        }
        System.out.println("程序结束");
    }
}

如果在try块或catch块中有return语句,finally是否还会执行?运行下面代码断点调试观察结果。

public class TestReturn {

    public static void main(String[] args) {
        try {
            int a=1+1;
            System.out.println("try执行");
            return;
        } catch (Exception e) {
            System.out.println("catch执行");
        }finally {
            System.out.println("finally执行");
        }
    }
}

try块或catch块中可以有return语句,如果有return语句会先执行finally最后再执行return。

多重catch

try块中可能会发生多种异常,如果要不同的异常进行不同的处理,需要使用多重catch进行处理。

语法:

public void method(){
    try{
        //可能发生异常的代码段
    }catch(异常类型1 e){
        //对异常类型1进行的处理的代码段
    }catch(异常类型2 e){
        //对异常类型2进行的处理的代码段
    }catch(异常类型n e){
        //对异常类型n进行的处理的代码段
    }
}

当try块中发生异常后,会逐个与catch中的异常类型进行匹配,匹配成功后,进入对应的catch进行异常处理,处理完成后不再进入其他catch,程序继续执行。

排列catch语句的顺序是:先子类后父类

发生异常时按顺序逐个匹配

只执行第一个与异常类型匹配的catch语句

将之前的代码 DemoInput.java 改造成多重catch

import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class DemoInput {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try{
            System.out.println("请输入被除数(整数):");
            int a=input.nextInt();
            System.out.println("请输入除数(整数):");
            int b=input.nextInt();
            int c=a/b;
            System.out.println("结果:"+c);
        }catch(InputMismatchException e) {
            System.out.println("输入的数有误!");
        }catch(ArithmeticException e) {
            System.out.println("除数不能为0");
        }catch(Exception ex) {
            System.out.println("发生未知异常");
        }finally {
            System.out.println("感谢您的使用");
        }
        System.out.println("程序结束");
    }
}

声明异常 throws

如果一个方法体内抛出了异常如何通知调用者,可以在方法上声明异常。


public class TestThrows {

    //声明异常,多个异常可以用逗号隔开
    public void test()throws Exception,ClassNotFoundException{
        //可能会发生异常的代码
    }
}

处理方式一:调用者处理异常

public static void main(String[] args) {
    TestThrows t=new TestThrows();
    try {
        t.test();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

处理方式二:调用者继续声明异常

public static void main(String[] args) throws ClassNotFoundException, Exception {
    TestThrows t=new TestThrows();
    t.test();
}

main方法继续声明异常,调用者就变成虚拟机了,发生异常则按默认方式处理,打印出来。

抛出异常 throw

除了系统自动抛出的异常外,有些问题需要程序员自行抛出异常

public class TestThrow {
    public void inputAge(int age) throws Exception {
        if (age<1) {
            throw new Exception("还有这种年龄?");
        }
    }

    public static void main(String[] args) {
        TestThrow t=new TestThrow();
        try {
            t.inputAge(-1);
        } catch (Exception e) {
            System.out.println("年龄有误:"+e.getMessage());
        }
    }
}

自行抛出异常后,还需要在方法上声明异常

原文地址:https://www.cnblogs.com/AIThink/p/9846642.html

时间: 2024-08-30 12:10:10

Java入门系列-20-异常的相关文章

好程序员Java教程系列之异常定义

好程序员Java教程分享Java系列之异常定义 异常定义 异常:就是程序在运行的过程中遇到的种种不正常的情况. 特点:如果一个程序在运行中遇到了一个未经处理的异常,则这个异常会终止程序的运行. ? 但是如果程序出现的异常被处理了,此时程序不会被终止.所以我们需要知道怎么去处理异常. 其实在Java中,异常也是一个类. 类的体系: Throwable: 是所有的异常的根类 Error: 发生在编译器级别的,我们程序无法处理的错误. Exception: 我们可以去处理的异常. RuntimeExc

Java 基础系列:异常

Java 中的异常(Exception)又称为例外,是一个在程序执行期间发生的事件,它中断正在执行的程序的正常指令流.为了能够及时有效地处理程序中的运行错误,必须使用异常类. 1. 异常类型 Throwable是Java中异常的根类,它有两个子类: Exception:是程序本身可以处理的异常.异常处理通常就是针对这种类型异常的处理.它也可以细分为两个方向: 非检查异常(运行时异常):编译器不要求强制处理的异常,程序员可以不管也可以捕获. 例:空指针异常.数组下标越界.算数异常.类型转换异常等等

Java入门系列:实例讲解ArrayList用法

本文通过实例讲解Java中如何使用ArrayList类. Java.util.ArrayList类是一个动态数组类型,也就是说,ArrayList对象既有数组的特征,也有链表的特征.可以随时从链表中添加或删除一个元素.ArrayList实现了List接口. 大家知道,数组是静态的,数组被初始化之后,数组长度就不能再改变了.ArrayList是可以动态改变大小的.那么,什么时候使用Array(数组),什么时候使用ArrayList?答案是:当我们不知道到底有多少个数据元素的时候,就可使用Array

Java入门系列-11-类和对象

这篇文章为你搞懂类和对象的使用 对象:用来描述客观事物的实体,由一组属性和方法组成,万物皆对象. 属性:就是对象的特征,像身高.体重.颜色 方法:对象的行为,如跑.跳 类:类是模子,定义对象将会拥有的属性和方法.类是抽象的概念,比如"书" 定义类 语法: public class 类名{ 属性1的类型 属性1; 属性n的类型 属性n; -- 方法1; 方法m; -- } 定义类可以按照3个步骤 1.定义类名 2.编写类的属性 3.编写类的方法 敲一敲:学生类 public class

Java入门系列-04-java中的变量

这篇文章为你搞懂三个问题 什么是变量? 如何使用变量? 变量命名有哪些规范? 变量 计算机的内存类似于人的大脑,电脑使用内存来存储计算所需要的数据. 内存像旅馆一样,不同的房间类型对应不同的数据类型,内存存储数据时会根据数据的需求为它申请一块合适的空间.用于存储数据的这个空间就是变量. 变量名 内存地址 值 name 0x5c2a0c3f.. 张三 age 0xcd4d72a... 10 变量名.内存和存储的值如上表↑ 可以看到内存地址长而不方便记忆,但是变量名可以像给一个人起外号一样,方便记忆

Java入门系列-12-成员方法

类的方法 无参方法 语法: public 返回值类型 方法名(参数列表){ //方法的主体 } 敲一敲:无返回值方法 public void sayHi(){ System.out.println("你好"); } 没有返回值返回值类型为 void ,上例中是无返回值.如果方法中有返回值,方法中必须使用关键之 return 返回该值,返回值类型为该返回值的类型. 敲一敲:有返回值方法 public class Student { String name; int age; /** *

Java入门系列-05-数据类型和类型转换

这篇文章为你搞懂2个问题 java 中有哪些数据类型可以用存储数据? java 中的数据类型是怎么转换的? 在上一篇文章中我们学会了如何使用变量,像这样存储一个整数 int age=10;,可以在开发工具中编写一行这样的代码 int age=10.5; 就会发现开发工具报错了,是因为变量中的数据类型也是不能随便用的. 数据类型 咱们先来看下面一组数据 如果每天花费2小时在交通上 1月=60小时=2.5天, 1年=730小时=30天, 50年=36500小时=1520天=4年 这段数据中可以分为以

Java入门系列-06-运算符

这篇文章为你搞懂2个问题 java 中的常用运算符有哪些?如何使用? 这些运算符的运算优先级是怎样的? 算数运算符 明显是做数学运算的,包括以下符号: + 加法运算 敲一敲: public class DemoAdd { public static void main(String[] args) { int sum=2+3; System.out.println(sum);//输出变量 sum 的值 int a=5; int b=3; int result=a+b;//将变量 a 的值与变量

Java入门系列-21-多线程

什么是线程 在操作系统中,一个应用程序的执行实例就是进程,进程有独立的内存空间和系统资源,在任务管理器中可以看到进程. 线程是CPU调度和分派的基本单位,也是进程中执行运算的最小单位,可完成一个独立的顺序控制流程,当然一个进程中可以有多个线程. 多线程:一个进程中同时运行了多个线程,每个线程用来完成不同的工作.多个线程交替占用CPU资源,并非真正的并行执行. 使用多线程能充分利用CPU的资源,简化编程模型,带来良好的用户体验. 一个进程启动后拥有一个主线程,主线程用于产生其他子线程,而且主线程必