java systemexception_Java 异常基础 Exception

Java中的异常 Exception

java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是所有异常的根类。

比如程序:

public classExceptionTest

{public static voidmain(String[] args)

{int a = 3;int b = 0;int c = a /b;

System.out.println(c);

}

}

编译通过,执行时结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)

因为除数为0,所以引发了算数异常。

比较常见的异常还有这种:空指针异常

java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但却调用了它的某个方法,这时就会出现该异常。

Java中的异常分为两大类:

1.Checked Exception(非Runtime Exception)

2.Unchecked Exception(Runtime Exception)

运行时异常

RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。

Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常。

异常处理的一般结构

try{//可能发生异常的代码//如果发生了异常,那么异常之后的代码都不会被执行

}catch(Exception e)

{//异常处理代码

}finally{//不管有没有发生异常,finally语句块都会被执行

}

比如本文最开始的除法运算代码,加入异常处理之后:

public classExceptionTest

{public static voidmain(String[] args)

{int c = 0;try{int a = 3;int b = 0;//这块代码出现了异常

c = a /b;//那么异常之后的代码都不会被执行

System.out.println("Hello World");

}catch(ArithmeticException e)

{

e.printStackTrace();

}finally{//不管有没有发生异常,finally语句块都会被执行

System.out.println("Welcome");

}

System.out.println(c);//当b为0时,有异常,输出为c的初始值0}

}

多个catch

一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。

异常处理方法

对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。

处理方式有两种:

1.使用try..catch..finally进行捕获;

2.在产生异常的方法声明后面写上throws某一个Exception类型,如throws Exception,将异常抛出到外面一层去。

对非运行时异常的处理详见代码例子:

处理方式1:将异常捕获

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png将异常捕获

public classExceptionTest2

{public void method() throws Exception //将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理

{

System.out.println("Hello World");//抛出异常

throw newException();

}public static voidmain(String[] args)

{

ExceptionTest2 test= newExceptionTest2();try{

test.method();

}catch(Exception e)

{

e.printStackTrace();

}finally{

System.out.println("Welcome");

}

}

}

处理方式2:将异常继续向外抛出

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png将异常抛出

public classExceptionTest2

{public void method() throws Exception //将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理

{

System.out.println("Hello World");//抛出异常

throw newException();

}public static void main(String[] args) throws Exception //main方法选择将异常继续抛出

{

ExceptionTest2 test= newExceptionTest2();

test.method();//main方法需要对异常进行处理//执行结果://Hello World//Exception in thread "main" java.lang.Exception//at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)//at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)

}

}

对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。

自定义异常

所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。

通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。

自定义异常可以用于处理用户登录错误,用户输入错误提示等。

自定义异常的例子:

自定义一个异常类型:

public class MyException extendsException

{publicMyException()

{super();

}publicMyException(String message)

{super(message);

}

}

一种异常处理方式:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png一种异常处理方式

public classExceptionTest4

{public void method(String str) throwsMyException

{if(null ==str)

{throw new MyException("传入的字符串参数不能为null!");

}else{

System.out.println(str);

}

}public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出

{

ExceptionTest4 test= newExceptionTest4();

test.method(null);

}

}

另一种异常处理方式:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png异常处理方式二

public classExceptionTest4

{public void method(String str) throwsMyException

{if (null ==str)

{throw new MyException("传入的字符串参数不能为null!");

}else{

System.out.println(str);

}

}public static voidmain(String[] args)

{//异常处理方式2,采用try...catch语句

try{

ExceptionTest4 test= newExceptionTest4();

test.method(null);

}catch(MyException e)

{

e.printStackTrace();

}finally{

System.out.println("程序处理完毕");

}

}

}

前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块。

下面这个例子,定义了两种自定义的异常类型:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png多种异常

public class MyException extendsException

{publicMyException()

{super();

}publicMyException(String message)

{super(message);

}

}public class MyException2 extendsException

{publicMyException2()

{super();

}publicMyException2(String message)

{super(message);

}

}public classExceptionTest4

{public void method(String str) throwsMyException, MyException2

{if (null ==str)

{throw new MyException("传入的字符串参数不能为null!");

}else if ("hello".equals(str))

{throw new MyException2("传入的字符串不能为hello");

}else{

System.out.println(str);

}

}public static voidmain(String[] args)

{//异常处理方式2,采用try...catch语句

try{

ExceptionTest4 test= newExceptionTest4();

test.method(null);

}catch(MyException e)

{

System.out.println("进入到MyException catch块");

e.printStackTrace();

}catch(MyException2 e)

{

System.out.println("进入到MyException2 catch块");

e.printStackTrace();

}finally{

System.out.println("程序处理完毕");

}

}

}

我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。

如果异常类型是独立的,那么它们的前后顺序没有要求。

如对上面的代码进行改动后,如下列出:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png多个catch语句块的顺序

public classExceptionTest4

{public void method(String str) throws Exception //也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可

{if (null ==str)

{throw new MyException("传入的字符串参数不能为null!");

}else if ("hello".equals(str))

{throw new MyException2("传入的字符串不能为hello");

}else{

System.out.println(str);

}

}public static voidmain(String[] args)

{//异常处理方式2,采用try...catch语句

try{

ExceptionTest4 test= newExceptionTest4();

test.method(null);

}catch(MyException e)

{

System.out.println("进入到MyException catch块");

e.printStackTrace();

}catch(MyException2 e)

{

System.out.println("进入到MyException2 catch块");

e.printStackTrace();

}catch(Exception e)

{//虽然需要加上,但是这块代码不会被执行,只是为了编译成功

System.out.println("进入到MyException catch块");

e.printStackTrace();//如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块//catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误

}finally{

System.out.println("程序处理完毕");

}

}

}

面试常考题型

try块中的退出语句

虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png笔试面试题解析

public classExceptionTest5

{public voidmethod()

{try{

System.out.println("进入到try块");//return;//会先执行finally块再返回//虚拟机退出//System.exit(0);//不会执行finally块中的语句,直接退出

}catch(Exception e)

{

System.out.println("异常发生了!");

}finally{

System.out.println("进入到finally块");

}

System.out.println("后续代码");

}public static voidmain(String[] args)

{

ExceptionTest5 test= newExceptionTest5();

test.method();

}

}

在加上return语句前,程序输出:

进入到try块

进入到finally块

后续代码

如果在try块中加入return语句:

程序执行输出:

进入到try块

进入到finally块

说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。

如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。

参考资料

圣思园张龙老师Java SE系列视频教程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向切面编程(AOP)的主要目的是将横切关注点(如日志记录、性能统计和事务处理等)与核心业务逻辑分离。在异常处理方面,AOP可以帮助我们将异常处理逻辑从业务代码中抽离出来,提高代码的可读性和可维护性。 以下是一个基于AOP的Java异常处理示例: 1. 定义一个异常处理类,该类实现了Spring框架的AfterThrowingAdvice接口: ```java public class ExceptionHandler implements AfterThrowingAdvice { public void afterThrowing(Method method, Object[] args, Object target, Exception ex) { // 根据异常类型进行不同的处理 if (ex instanceof BusinessException) { // 业务异常 // 记录日志或者发送通知等操作 } else if (ex instanceof SystemException) { // 系统异常 // 发送通知或者触发告警等操作 } else { // 其他异常 // 记录日志或者发送邮件等操作 } } } ``` 2. 在Spring的配置文件中定义切面和切点: ```xml <bean id="exceptionHandler" class="com.example.ExceptionHandler" /> <aop:config> <aop:aspect ref="exceptionHandler"> <aop:pointcut id="exceptionPointcut" expression="execution(* com.example..*(..))" /> <aop:after-throwing pointcut-ref="exceptionPointcut" throwing="ex" method="afterThrowing" /> </aop:aspect> </aop:config> ``` 这里我们定义了一个切面ExceptionAspect,它引用了前面定义的ExceptionHandler类。我们使用<aop:pointcut>元素定义了一个切点,它匹配所有com.example包及其子包下的方法。最后,在<aop:after-throwing>元素中,我们将切点和异常处理方法关联起来。 3. 在业务代码中抛出异常: ```java public void doSomething() throws BusinessException { // ... if (someCondition) { throw new BusinessException("业务异常"); } // ... } ``` 在业务代码中,我们可以通过throw语句抛出业务异常。当异常被抛出时,AOP框架会自动调用ExceptionHandler中定义的afterThrowing方法进行处理。 通过使用AOP框架,我们可以将异常处理逻辑与业务代码分离,提高代码的可读性和可维护性。同时,我们也可以将不同类型的异常进行分类处理,以便更好地监控和管理系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值