Java异常简介

三种异常类型
  1. 检查性异常:最具代表的检查异常时用户错误或问题引起的异常,这是程序员无法预见的,例如要打开一个不存在的文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  2. 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  3. 错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

Throwable(异常的超类)

  1. ERROR(错误)

    • VirtulMachineError(虚拟机异常)
      • StackOverFlowError
      • OutOfMemoryError
    • AWTError(GUI编程图形界面化异常)
  2. Exception(异常)

    • IOException(IO异常)
      • EOFException
      • FileNotFoundException
    • RuntimeException(运行时异常)
      • ArrithmeticException(算数异常)
      • MissingResourceException(丢失资源)
      • ClassNotFoundException(找不到类)
      • NullPointerException(空指针异常)
      • IllegalArgumentException
      • ArrayIndexOutOfBoundsException(数组下标越界异常)
      • UnkownTypeException(未知的类型异常)
Error与Exception区别

Error通常时灾难性的致命错误,时程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

异常处理机制
  • 抛出异常

  • 捕获异常

  • 异常处理五个关键字:

    • try、catch、finally、throw、throws
    捕获异常 try…catch

    捕获异常:Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式处理。

    捕获异常语法如下:

    try:该代码块中编写可能产生异常的代码。

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

    注意:try和catch都不能单独使用,必须连用。

    Finally 块

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

    什么时候的代码必须最终执行?

    当我们在try语句块中打开了一些物理资源(如 IO流、网络、数据库链接等),都需在使用完之后,最终关闭打开的资源。

    finally 的语法: try…catch…finally:自身需要处理异常,最终还得关闭资源。

    注意:finally 不能单独使用。

package com.exception;
public class Test {
    public static void main(String[] args) {
        int a=1;
        int b=0;
        //快捷键 ctrl+alt+t
        System.out.println(a/b);
        //要捕获多个异常:从小到大!
        try {//try监控区域
            new Test().a(); //可能出现异常的代码
        }catch (ArithmeticException e){//catch(想要捕获的异常类型!) 捕获异常
            System.out.println("程序出现异常,变量b不能为0" );//处理异常的代码 记录日记 打印异常信息 继续抛出异常
        }catch (Error e){
            System.out.println("Error");
        }catch (Exception e){
            System.out.println("Exception ");
        } finally {//处理善后工作
            System.out.println("finally");
        }
        //finally 可以不要finally 假设IO,资源,关闭!
    }
    public void a(){
        b();
    }
    public void b(){
        a();
    }
} 
抛出异常 throw

在Java中,提供一个throw关键字,它用来抛出一个指定的异常对象。

  1. 创建一个异常对象。封装一些提示信息(信息可以自己编写)
  2. 需要将这个异常对象告知调用者。通过关键字throw将这个异常对象传递到调用者处。throw用在方法内,用来抛出一个异常对象,将使用格式: throw new 异常类名(参数—你想告知用户的异常信息);

注意:如果产生了问题,我们通过throw将异常进行抛出,也就是将问题返回给该方法的调用者。那么调用者该怎么处理那?一种是进行捕获处理,另一种就是继续将问题生命出去,使用throws声明处理。

声明异常 throws

将问题标识出来,报告给调用者。如果方法内通过throw抛出了 编译时异常,而没有捕获处理,那么必须通过throws 进行声明,让调用者去处理。关键字 throws 运用于方法声明上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。

声明异常语法: 修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{}

throws 用于进行异常的声明,若该方法可能有多种异常情况产生,那么在 throws 后面可以写多个异常类,用逗号隔开。最大的异常习惯放后面。

异常处理两种方式

如果异常出现的话,会立刻终止程序,所以我们得处理异常:

  1. 声明异常:throws该方法不处理,而是声明可能出现的异常,将问题暴露给调用者,让调用者自己处理!
  2. 捕获异常:try catch 在方法中使用try-catch的语句块直接处理可能出现的异常!
package com.exception;
public class Test2 {
    public static void main(String[] args) {
        try {
            new Test2().test(1,0);
        }catch(ArithmeticException e){
            e.printStackTrace();
        }
    }
    //假设这方法中,处理不了这个异常。方法上抛出异常
    public void test(int a,int b){
        if(b==0){//throw throws
            throw new ArithmeticException();//主动的抛出异常,一般在方法中使用
        }
    }
}
异常注意事项

多个一擦汗给你使用捕获又该如何处理?

  1. 多个异常分别处理。
  2. 多个异常一次捕获,多次处理。
  3. 多个异常一次捕获一次处理。

一般我们使用一次捕获多次处理的方法,格式如下:

try{
	//可能出现异常的代码
}catch(异常类型A e){//当 try 中出现A类型异常,就用该catch来捕获
    //处理异常的代码
    //记录日记/打印异常信息/继续抛出异常
}catch(异常类型B e){//当 try 中出现B类型异常,就用该catch来捕获
    //处理异常的代码
    //记录日记/打印异常信息/继续抛出异常
}

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

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

自定义异常

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

例如 自定义一个业务逻辑异常:PasswordErrorException。密码错误类。

异常类如何自定义:

  1. 自定义一个检查异常:自定义类 并继承于 java.lang.Exception
  2. 自定义一个运行时期的异常类:自定义类 并继承于 java.lang.RuntimeException
public static void main(String[] args) {
		UserService ser =new UserService();
		try {
            //异常可以处理,也可以不处理:运行时异常
			boolean res1=ser.validateName("test1");
			System.out.println(res1);
		} catch (UserNameIsNotExistException e) {
			e.printStackTrace();
		}
		try {
            //必须处理异常:有可能是检查异常
			boolean res=ser.login("teset1","teset");
			System.out.println(res);
		} catch (UserPwdErrorException e) {
			e.printStackTrace();
		}
	}
public class UserService {
	public boolean validateName(String name) {
		if(!name.equals("test")) {
			throw new UserNameIsNotExistException();
		}else {
			return true;
		}
	}
	public boolean login(String name,String pwd) throws UserPwdErrorException{
		if(name.equals(pwd)) {
			return true;
		}else {
			throw new UserPwdErrorException();
		}
	}
}
public class UserNameIsNotExistException extends RuntimeException{
	public UserNameIsNotExistException() {
		super("用户名不存在!");
	}
}
public class UserPwdErrorException extends Exception{
	public UserPwdErrorException() {
		super("用户名或密码错误!");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值