JAVA超详细:异常类型及处理(含实例)

3 篇文章 0 订阅

目录

异常的产生

异常的分类

异常的处理方法

throws和throw的区别

使用异常的技巧


异常的产生

Java 程序运行期间出现了一个错误 这个错误可能是由于文件包含了错误信息, 或者网络连接出现问题造成的 也有可能是因为使用无效的数组下标 或者试图使用一个没有被赋值的对象引用而造成的。此时用户希望:
  • 返回到一种安全状态并能够让用户执行一些其他的命令
  • 允许用户保存所有操作的结果 并以妥善的方式终止程序
常见的错误有这几种类型:
  • 用户输入的错误
  • 设备错误
  • 物理限制
  • 代码错误

异常的分类

java中的异常的类都来源于java.lang的包中,这是Java程序会自动导入的包,不需要手动import

Java中的异常都派生于Throwable类,可以分为两大类:

  • 运行时异常,也成为非检查型异常
  • 非运行时异常,也成为检查时异常

Throwable类

Throwable类是所有异常类的子类,所有的异常对象都是派生于Throwable类的实例。Throwable类在异常界的地位就像Object类在所有类中的地位。

Error类(非检查型异常)

Error在英语中是错误的意思,Error类描述了运行时内部错误和资源耗尽的错误。

程序不应该抛出这种类型的对象,这种错误一旦出现,一般的解决办法是妥善的终止程序,程序几乎不能处理,属于大问题。

常见的Error异常 Error错误的全部类

IOError当出现严重的I/O异常时抛出
ThreadError在受害的线程中抛出

RuntimeException类(非检查型异常)

由编译错误导致的异常属于RuntimeException异常。常常包括以下问题:

  • 错误的强制类型转换
  • 数组的越界访问
  • 指针指向空指针,访问空指针

常见的RuntimeException异常 RuntimeException异常的全部类

 ArithmeticException数字计算的异常。例如除数为0会抛出此异常
NullPointerException空指针异常
ArrayOutOfBoundsException数组越界产生的异常
ClassNotFoundException找不到类文件的异常
ClassCastException类文件强制转化的异常

 数字计算错误的异常举例:

try{

int i = 3 ;
int j = 0 ;
System.out.println(i/j); 

catch(ArithmeticException e){
 System.out.println("除数不能为0!"); 
}
}

IOException类(检查型异常)

输入输出等找不到路径的异常属于IOException异常。常常包括以下问题:

  • 试图超越文件末尾继续读取文件
  • 试图打开一个不存在的文件
  • 属兔查找一个不存在的类

常见的IOException类异常 IOException类的全部子类

FileNotFoundException文件不存在时抛出的异常
IIOException读写操做的异常
EOFException遇到文件或流的结尾的异常

 文件的异常举例:

try{
 var in =new FileInputStream(filename);
 int b;
 while((b=in.read())!=-1)
{
   //代码段

}
}
carch(IOException e){
  //打印一个堆栈的轨迹
  e.printStackTrace();
}
}

异常的处理方法

一、try--catch--finally方法

try{ //代码段 }

catch(异常的类名 对象名){ //代码处理段 }

........

catch(异常的类名 对象名){ //代码处理段 }

finally{  // 代码段}

  • 其中try和catch必须同时出现 ,但是finally可以不出现
  • try中的语句是必须运行的,在try中可能会有异常的抛出
  • catch中接受try中抛出的异常,可能没有异常,则不执行catch的代码
  • finally是必须执行的代码段,不论有没有异常
  • catch可以有多个,用来处理不同类型的异常

从中可以看到try-catch-finally语句是可以嵌套的,即可以有异常中的异常出现

try{ 

try{ //代码段 }

catch(异常的类名 对象名){ //代码处理段 }

finally{  // 代码段}

}

catch(异常的类名 对象名){ //代码处理段 }

........

catch(异常的类名 对象名){ //代码处理段 }

finally{ 

//代码段

try{ //代码段 }

catch(异常的类名 对象名){ //代码处理段 }

finally{  // 代码段}

}

throw抛出异常

如果需要在程序中自行抛出异常,则应使用 throw 语句,throw 语句抛出是一个异常实例,而且每次只能抛出一个异常实例。

try{ //代码段}

catch(Exception e){ throw e...} ......

catch(SQLException e){
   throw new ServleException("error"+e.getMassage());
}

//可以改写为
catch(SQLException e){
   var es=new ServleException("error");
   es.initCause(e);
   throw es;
}

二、用throws声明,将异常传递给调用者

不用写出具体的异常处理方法,而是将其传播,但必须在方法的首部添加一个 throws 说明符,提醒调用者这个方法可能抛出的异常

上面文件的IOException的异常就可以改写为:

public void read(String filename) throws IOException{
 var in =new FileInputStream(filename);
 int b;
 while((b=in.read())!=-1)
{
  //代码段
}

虽然这个方法不叫简洁,但是有几个要注意的点:

  • 如果编写一个方法覆盖超类方法,而这个超类方法没有抛出异常,就必须捕获你的方法中出现的每一个检查型异常
  • 不允许在子类的throws中出现超类中方法没有出现的异常

throws和throw的区别

  • throws用于异常方法的声明,throw在方法体内使用
  • throws后面是异常类型,可以有多个;throw后面是异常的实例对象,只能有一个
  • throws用来声明,由调用者处理,不一定会出现异常;throw是出现异常时手动来结束方法的,执行了throw一定会出现异常

使用异常的技巧

  1. 异常的处理不能代替简单的测试 

例如我们要强制要求空栈弹出若干次,首先判断是否为空栈

if(!s.empty())
s.pop();

而用异常的方法则要求我们不能这样做

try{
s.pop();
}
catch(EmptyStackException e){}

isempty方法的运行时间远小于异常的方法,因此,异常仅在异常的情况下使用

  2.不要尽量细化异常

细化异常会使代码的量急剧增加,运行效率会降低

//例如将try嵌套在for循环中
for(int i = 0; i < 100 ; i ++){
try{ s.pop()}
catch(....){}

//尽量写成
try{
for(int i = 0 ; i < 100 ; i ++){
s.pop();
}
catch(......){}

将整个任务包在一个try中,这样出现问题就可以取消整个程序

  3.充分利用异常的层次结构

  • 不要只抛出RuntimeException异常,找寻一个适合的子类或子集创建一个子类
  • 不要只捕获Throwable异常,否则代码很难维护

  4.宁愿严格处理异常,也不要放任

  • 12
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值