Java 中的异常和处理【基础巩固】(个人理解有限+整理资料,勿喷)

今天在一个交流群里看有人发了面试题,里面有道题"谈谈对java的异常处理机制的认识,并写出常见的5种异常",晃眼一看不就是异常么,5种异常随口就来。见群里噼里啪啦一堆异常的名字闪现,发题的人问了“那java的异常处理机制是什么?”,看到这话心里一顿嘲讽“这么简单还问,你个小菜鸡”,但是仔细一想java 的异常处理机制真的要往细一点说好像自己也忘了,说不了多少啊!所以就想着巩固下java的基础,后续一段时间都会写java的基础知识吧!以下正文了

异常是什么?官方一点 程序运行时,发生的不被期望的事件,它阻止了程序按照开发人员的预期正常执行。那么异常发生时,是不闻不问还是终止程序?或者提示给用户?此处就要引出我们的java非常优秀的异常处理机制了。

java异常处理机制能让程序在异常发生时,按照预先设定的异常处理逻辑处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。

Java异常的分类

Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。

Throwable又派生出Error类和Exception类。

错误:Error类以及他的子类的实例,代表了JVM本身的错误,错误不能被程序员通过代码处理,Error很少出现,出现Error(JVM)一般会选择终止线程。因此我们编写程序时不需要关心这类异常。(记得当初来时的原话是“出现Error错误的时候你们就别去管了,反正看了也解决不了”,想想都扎心)

异常:Exception以及他的子类,比如NullPointerException、IndexOutOfBoundsException,这些异常是我们可以处理的异常,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

Exception类的异常包括unchecked exception(非检查异常),也称运行时异常(RuntimeException 运行时异常并不是前面我所说的运行期间的异常,只是Java中用运行时异常这个术语来表示,Exception类的异常都是在运行期间发生的),比如常见的NullPointerException、IndexOutOfBoundsException。对于运行时异常,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定;checked exception(检查异常),也称非运行时异常(运行时异常以外的异常就是非运行时异常),java编译器强制编程人员必须进行捕获处理(使用try…catch…finally或者throws),比如常见的IOExeption和SQLException。对于非运行时异常如果不进行捕获或者抛出声明处理,编译都不会通过。(网上有资料把Error 也分在了非检查异常里面)

上个图(不会画,图有点丑,将就看是哪个意思就行)

Java中如何处理异常

扯了那么多让我们来看看如何处理异常:在Java中如果需要处理异常,首先先对异常进行捕获,然后再对异常情况进行处理。关键字try和catch...finally用来捕获处理异常稳得一匹(忍不住皮一下),或者,在函数签名中使用throws 声明交给函数调用者caller去解决

try和catch...finally如下面一段代码所示:

try{
     //try块中放可能发生异常的代码。
     //如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
     //如果发生异常,则尝试去匹配catch块。
     //try语句可以被嵌套
 
}catch(ArithmeticException e){
    //每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。
    //catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
    //在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
    //如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
    //如果try中没有发生异常,则所有的catch块将被忽略。
 
}catch(Exception exception){
    //...
}finally{
 
    //finally块通常是可选的。
   //无论异常是否发生,异常是否匹配被处理,finally都会执行。
   //一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
  //finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。 
}

值得注意的是对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子句放在前面,同时尽量将捕获相对高层的异常类的catch子句放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。

throws 函数

throws声明:如果一个方法内部的代码会抛出检查异常(checked exception),而方法自己又没有完全处理掉,则javac保证你必须在方法的签名上使用throws关键字声明这些可能抛出的异常,否则编译不通过。如果是不受检查异常(unckecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出

throws是另一种处理异常的方式,它不同于try…catch…finally,throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。

采取这种异常处理的原因可能是:方法本身不知道如何处理这样的异常,或者说让调用者处理更好,调用者需要为可能发生的异常负责

	public void info() throws ExceptionType1 , ExceptionType2 ,...,ExceptionTypeN{ 
	     //info内部可以抛出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 类的异常
         //或者他们的子类的异常对象。
	}

throw 异常抛出语句

throw AppException

程序开发人员也可以通过throw语句手动显式的抛出一个明确的异常。throw语句的后面必须是一个异常对象。

throw 语句必须写在函数中,执行throw 语句的地方就是一个异常抛出点,程序执行完throw 语句之后立即停止,throw 后面的任何语句不被执行。最邻近的try块用来检查它是否含有一个与异常类型匹配的catch语句。


try {
	if(tempMeet==null){
        throw new AppException("当前修改的会议信息不存在,修改失败");
    }
} catch (AppException appException) {
	.....
} catch (Exception e) {
	.....
}

自定义异常

Java内置的异常类可以描述在编程时出现的大部分异常情况。但是除此之外,用户还可以自定义异常(上面的BaseException就是自定义异常)。则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

自定义异常的使用一般步骤

1、创建自定义异常类(例如:AppException )

public class AppException extends BaseException{
  public AppException(String message){
    super(message);
  }

  public AppException(String code, String message){
    super(code, message);
  }

  public AppException(String code, String message, Exception ex){
    super(code, message, ex);
  }
}

2、在方法中通过throw关键字抛出异常对象

if(tempMeet==null){
   throw new AppException ("当前修改的会议信息不存在,修改失败");
}

3、如果当前跑出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作


try {
	if(tempMeet==null){
        throw new AppException ("当前修改的会议信息不存在,修改失败");
    }
} catch (AppException  appException ) {
	.....
} catch (Exception e) {
	.....
}

4、在出现异常方法的调用者中捕获并处理异常


try {
	if(tempMeet==null){
        throw new AppException ("当前修改的会议信息不存在,修改失败");
    }
} catch (AppException  appException ) {
	logger.error(appException.getMessage(), appException.fillInStackTrace());//记录错误信息
} catch (Exception e) {
	logger.error(e.getMessage(), e.fillInStackTrace());//记录错误信息
}

以上就是今天梳理的关于java异常和处理的梳理了,中午吃完饭开始写写到现在,越往下写越是让我巩固基础的心思越活络。在写的途中同事问了一些关于java虚拟机的问题,我在想是不是下次要准备写个虚拟机的初步认识,实话实说从学校出来之后真的是没去仔细的了解java虚拟机,周末充个电,下周写个初认虚拟机吧

本人工作时间不长,平时比较懒很多知识都没有去仔细的了解,所以写的感觉有点乱七八糟,希望各位大佬多多指正。

转载于:https://my.oschina.net/u/3903095/blog/1844407

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值