前言

越是简单,越容易忽略。编码一切应该从简单开始,简单点,编码的方式简单点,正确点,对待异常的方式正确点。

一, JAVA异常类结构

Java异常类结构: Java异常类结构如下图。基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,NullPointerException继承RuntimeException,可以说,在Java中,除了Error之外,所有的异常类都直接或间接地继承自Exception。
正确的对待异常
Java异常分类:

① ,非运行时/编译时异常。在Java中,凡是继承自Exception但不是继承自RuntimeException的类都是非运行时异常,又称为编译时异常。

② ,运行时异常。Error和所有直接或间接地继承自RuntimeException的异常都是运行时异常,常见的有NullPointerException,IllegalArgumentException,IndexOutOfBoundsException等

Exception 含义
NullPointerException 指针
IllegalArgumentException 非法参数
IllegalStateException 非法状态
IndexOutOfBoundsException 索引出界
UnsupportedOperationException 不支持的操作
SQLException 操作数据库异常
ClassCastException 数据类型转换异常
NumberFormatException 字符串转换数字异常
ArithmeticException 除数为0的异常
BufferOverflowException 缓冲区上溢异常
BufferUnderflowException 缓冲区下溢异常
EmptyStackException 空栈异常

二, Android异常分类

1, Java异常

在Java中出现未捕获异常,导致程序异常终止退出。即上面说到的Java Exception中的RuntimeException。

2, ANR(Application Not Responding)

应用与用户进行交互时,在一定时间(如主线程输入事件中为5秒)内没有响应用户的操作,则会引发ANR错误,并弹出一个系统提示框,让用户选择继续等待或立即关闭程序。同时会在/data/anr目录下生成一个traces.txt文件,记录系统产生ANR异常的堆栈和线程信息。

3, Native异常

Native异常/崩溃指在Native代码(C/C++)中,因访问非法地址,地址对齐等问题,或程序主动abort所产生相应的Signal导致程序异常退出。Linux中定义了很多Signal,当然并不是所有的Signal都会引发崩溃,一般会引发异常退出的Signal有SIGSEGV,SIGABRT,SIGILL,SIGBUS,SIGFPE等。Native异常具有与Java异常不同的特点:

  • 程序会直接闪退到系统桌面。
  • 出错时不会弹出提示框提醒程序崩溃(Android5.0以下) 。

三, Android异常处理方法

1, 编译时异常

在编译阶段被处理的异常,编译器会强制程序处理所有的编译时异常,也就是用try…catch显式地捕获并处理。Java认为这类异常都是可以被处理/修复的,同时在Java API文档的方法说明中,都会添加是否throw某个exception,这个exception就是编译时异常。

2, 运行时异常

在运行时没有相应的try…catch处理该异常对象,所以Java运行环境将会终止,程序将推出。针对这类异常处理方法:

  • 认为加try…catch。这是一种非常low,非常不可取的方法,因为如果所有代码都加try…catch,那么对代码真正问题所在,无法处理和解决该问题。当然这样做并不是不可取。
  • 个性化退出。我们可以在程序退出前,弹出一个个性化的对话框或者重启应用来代替Android系统默认强制退出应用程序。实现方式可以查阅资料,这里不做过多介绍。另外对于一些异常我们是可以做拦截操作的,比如空指针这类问题,如果出现了不让程序崩溃,但是这些方式本人建议尽量不要去做。因为程序中的异常本身可以看成是帮助我们查找问题,和提升程序的稳定性的,去掉或者中和掉得不偿失。

四, 正确使用try…catch

  • 需要异常捕获的地方,比如:类型转换等。不要随意去添加异常,分析代码稳定性。
  • 如果有多个Exception,不要利用Exception捕获所有潜在的异常。
  • 如果try语句块中存在return语句,那么首先会执行finally语句块中的代码,然后才返回。
  • 如果try语句块中存在System.exit(0)语句,那么不会执行finally语句块的代码,因为System.exit(0)会终止当前运行的JVM,程序JVM终止前结束执行。
  • 当使用多个catch语句块来捕获异常时,需要将父类的catch语句块放到子类型的catch块之后,这样才能保证后续的catch可能被执行,否则子类型的catch将永远无法到达,Java编译器会报编译错误。
  • 不要将异常包含在for循环语句中,因为异常处理是占用资源的。

相关文章:

  • 2021-12-27
  • 2022-01-04
  • 2021-10-30
  • 2021-07-25
  • 2021-11-08
  • 2021-08-27
  • 2021-07-27
猜你喜欢
  • 2021-11-10
  • 2021-12-27
  • 2021-09-13
  • 2021-06-04
  • 2021-10-15
相关资源
相似解决方案