Java异常

一.异常概念

1.异常概念

异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部 位和正常相比有点不同,该部位的功能将受影响.

异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的 非正常停止。

注意:

        Java是面向对象语言,异常本身也是一个类,当出现非正常的时候,就会创建该异常的对象并抛出异常对象

        创建的异常对象,该对象就会包装异常的类型,异常的信息,异常的位置等信息

2.异常体系

异常机制其实是帮助我们找到程序中的问题,异常的根类是 java.lang.Throwable ,其下有两个子类:java.lang.Error与 java.lang.Exception,平常所说的异常指java.lang.Exception。

 Throwable体系:

                Error:严重错误Error,无法通过处理的错误,只能实现避免,例如:栈内存溢出错误。服务器宕机,数据库崩溃...好比如绝症。

                Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续执行,是必须要处理的。好比感冒、阑尾炎。

3.异常分类

        编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)

        运行时期异常:runtime异常。在运行时期,检查异常。在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)

4.异常的产生过程解析

public class Test {
    public static void main(String[] args) {
        int[] arr = { 34, 12, 67 };
        int num = getElement(arr, 4);
        System.out.println("num=" + num);
        System.out.println("over");
   }
    // 对给定的数组通过给定的角标获取元素。
public static int getElement(int[] arr, int index) {
        int element = arr[index];
        return element;
   }
}

二.异常的产生

在Java中,提供一个thorw关键字,它用来抛出一个指定的异常对象。throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

 具体操作:

                创建一个异常对象。封装一些提示信息(信息可以自编写)。

                通过关键字throw将这个异常对象告知给调用者就可以完成。

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        // 在给年龄赋值时,先判断
if (age < 0 || age > 120){
            // 产生异常 运行异常
            throw new RuntimeException("年龄数据不合法");
       }else {
            this.age = age;
       }
   }
    public Person() {
   }
    public String getName() {
        return name;
   }
    public void setName(String name) {
        this.name = name;
   }
    public int getAge() {
        return age;
   }
    public void setAge(int age) {
        // 在给年龄赋值时,先判断
        this.age = age;
   }
}
public class DemoTest {
    public static void main(String[] args) {
        /*
            案例演示:给Person对象年龄赋值,如果年龄数据不合法,就产生
一个异常
        */
        // 创建Person类对象
        Person p1 = new Person("张三",18);
System.out.println(p1.getName()+"..."+p1.getAge());
        Person p2 = new Person("李四",-18);
       
 System.out.println(p2.getName()+"..."+p2.getAge());
   }
}

三.处理异常

1.声明处理异常

声明处理异常:使用throws关键字将异常标识出来,表示当前方法不处理异常,而是提醒给调用者,让调用者来处理...最终会到虚拟机,虚拟机直接结束程序,打印异常信息

public class DemoTest {
    public static void main(String[] args) throws 
Exception {
        
        /*
           声明处理异常:使用throws关键字将异常标识出来, 表示当前方
法不处理异常,而是提醒给调用者,
               让调用者来处理....最终会到虚拟机,虚拟机直接结束程序,
打印异常信息。
          声明处理异常格式
              修饰符 返回值类型 方法名(参数) throws 异常类名1,异
常类名2…{ // 可以抛出一个,也可以多个
                    }
          注意:
             声明处理异常,当程序产生了异常,还是会造成程序的异常终止,
导致程序无法继续往下执行
*/
        //method01();
        //method02(1);
        method03(1);
        
        System.out.println("结束");
   }
    // 处理多个异常 抛最大的一个异常
    public static void method03(int num) throws Exception 
{
        if (num == 1) {
            throw new ParseException("解析异常",10);
       } else {
            throw new IOException("IO异常");
       }
   }
    // 处理多个异常 分别抛出多个异常
    public static void method02(int num) throws 
ParseException,IOException{
        if (num == 1) {
            throw new ParseException("解析异常",10);
       } else {
            throw new IOException("IO异常");
       }
   }
    // 处理单个异常
    public static void method01() throws ParseException{// 
将异常标识出来,表示当前方法不处理异常
        // 产生一个异常
        throw new ParseException("解析异常",10);// 编译异常
        // throw new ArrayIndexOutOfBoundsException("索引越
界异常");// 运行异常
   }
}

2.捕获处理异常

捕获处理异常:对异常进行捕获处理,处理完后程序可以正常向下执行

try{
    编写可能会出现异常的代码
}catch(异常的类型 e){
    处理异常的代码
    //记录日志/打印异常信息/继续抛出异常
}

Throwable类中定义了一些查看方法:

        pbulic String getMessage():获取异常的描述信息,原因(提示给用户的时候,就提示错误信息)。

        public String toString():获取异常的类型和异常描述信息(不用)。

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

执行:

        如果try中的代码出现了异常,就会执行catch里面的代码,程序还会继续往下执行

        如果try中的代码没有出现异常,就不会执行catch里面的代码,程序还会继续往下执行

注意

        try和catch不能单独出现

        catch中的代码一定是try中的代码出现了异常才会执行

         try...catch结构执行完毕后,程序会继续向下执行

        try中某个位置出现了异常,那么该位置之后try中的代码就不会再执行

public class DemoTest {
    public static void main(String[] args){
        try{
            System.out.println("try开始");
            FileInputStream fis=new FileInputStream("D:\\2.txt");
            //创建异常对象并抛出 throw new FileNotFoundException("");
            System.out.println("try结束");
       }catch (IOException e){
            // 打印信息
            //System.out.println("出现了异常");
            //System.out.println(e.getMessage());
            //System.out.println(e.toString());
            e.printStackTrace();// 打印异常的跟踪栈信息
}
        System.out.println("结束");
        
   }
}
public class DemoTest {
    public static void main(String[] args){
        try{
            System.out.println("try开始");
            FileInputStream fis=new FileInputStream("D:\\1.txt");
            //创建异常对象并抛出 throw new FileNotFoundException("");
            System.out.println("try结束");
       }catch (IOException e){
            // 打印信息
            //System.out.println("出现了异常");
            //System.out.println(e.getMessage());
            //System.out.println(e.toString());
            e.printStackTrace();// 打印异常的跟踪栈信息
       }
        System.out.println("结束");
   }
}

3.finally代码块

        finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到,而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。

 

四.异常注意事项

运行时异常被抛出可以不处理。即不捕获也不声明抛出。

如果父类的方法抛出了多个异常,子类覆盖(重写)父类方法时,只能抛出相同的异常或者是他的子集。

父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

当多异常分别处理时,捕获处理,前边的类不能是后边类的父类

在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。

多个异常使用捕获又该如何处理呢?

         多个异常分别处理。

        多个异常一次捕获,多次处理。

        多个异常一次捕获一次处理、

public class DemoTest {
    public static void main(String[] args){
            method04(1);
   }
    public static void method04(int num) {
        try {
            if (num == 1) {
                throw new ParseException("解析异常",10);
           } else {
                throw new Exception("IO异常");
           }
       } catch (Exception e) {
            e.printStackTrace();
       } /*catch (ParseException e){// 当多异常分别处理时,捕
获处理,前边的类不能是后边类的父类
        }*/
   }
    // 3. 多个异常一次捕获,多次处理。
public static void method03(int num) {
        try {
            if (num == 1) {
                throw new ParseException("解析异常",10);
           } else {
                throw new IOException("IO异常");
           }
       } catch (Exception e) {
            e.printStackTrace();
       }
   }
    // 2. 多个异常一次捕获,多次处理。
    public static void method02(int num) {
        try {
            if (num == 1) {
                throw new ParseException("解析异常",10);
           } else {
                throw new IOException("IO异常");
           }
       } catch (ParseException e) {
            e.printStackTrace();
       } catch (IOException e) {
            e.printStackTrace();
       }
   }
    // 1. 多个异常分别处理。
    public static void method01(int num) {
        if (num == 1) {
            try {
                throw new ParseException("解析异常",10);
           } catch (ParseException e) {
                e.printStackTrace();
           }
       } else {
            try {
                throw new IOException("IO异常");
} catch (IOException e) {
                e.printStackTrace();
           }
       }
   }
}

五.自定义异常、

我们说了Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开 发中总是有些异常情况是SUN没有定义好的,例如年龄负数问题,考试成绩负数问题.这些异常在JDK中没有定义过,此时我们根据自己业务的异常情况来 定义异常类。

异常类如何定义:

 要求:我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该 用户名已经被注册。

        首先定义一个注册异常类RegisterException:

         模拟登陆操作,使用数组模拟数据库中存储的数据,并提供当前注册账 号是否存在方法用于判断。

public class DemoTest {
    public static void main(String[] args){
// 1.定义一个字符串,表示已经注册的用户名
        String username = "admin";
        // 2.创建Scanner对象,获取用户输入的用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要注册的用户名:");
        String name = sc.next();
        // 3.判断
        if (username.equals(name)){
            // 产生注册异常
            try {
                throw new RegisterException("亲,该用户名已经
被注册。");
           } catch (RegisterException e) {
                System.out.println(e.getMessage());
           }
       }else{
            System.out.println("恭喜您,注册成功");
       }
        System.out.println("结束");
   }
}

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值