异常的第一种处理方式throws。

看以下例子:

import java.io.*;
public class ExceptionTest04{
 public static void main(String[] args){
   m1(); 
 }
 public static void  m1(){
   m2();
 }
 public static void m2(){
   m3();
 }
 public static void m3(){
   new FileInputStream("c:/ab.txt");  //FileInputStream构造方法声明位置上使用throws(向上抛)
  }
}

以上代码编译时出错:

ExceptionTest04.java:16: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
                new FileInputStream("c:/ab.txt");

按照提示修改之后:

import java.io.*;
public class ExceptionTest04{
 public static void main(String[] args){
   m1(); 
   System.out.println("hello");
 }
 public static void m1(){
   m2();
 }
 public static void m2(){
   m3();
 }
 public static void m3() throws FileNotFoundException{
   new FileInputStream("c:/ab.txt");
 }
}

编译时出错;

ExceptionTest04.java:30: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
             m3();

由此看出,修改之后m3()运行时出现错误,上抛给m2(),以此类推,m2()上抛异常给m1(),m1()上抛异常给main()方法。

因此作出如下修改:

import java.io.*;
public class ExceptionTest04{
 public static void main(String[] args) throws FileNotFoundException{
   m1(); 
   System.out.println("hello");
 }
 public static void m1() throws FileNotFoundException{
   m2();
 }
 public static void m2() throws FileNotFoundException{
   m3();
 }
 public static void m3() throws FileNotFoundException{
   new FileInputStream("c:/ab.txt");
 }
}

修改之后编译通过,但是System.out.println("hello")并不会执行。

从上面的例子中可以看出,使用throws处理异常不是真正处理异常而是推卸责任,谁调用就会抛给谁。上面的m1方法如果出现了异常,因为采用的是上抛,JVM遇到这个异常就会退出JVM,之后的代码不会执行。因此引入try...catch...方法。修改如下,编译运行通过,并且输出:hello。

import java.io.*;
public class ExceptionTest04{
 public static void main(String[] args) throws FileNotFoundException{
   try{
     m1();
   }  catch(FileNotFoundException e){}
   System.out.println("hello");
 }
 public static void m1() throws FileNotFoundException{
   m2();
 }
 public static void m2() throws FileNotFoundException{
   m3();
 }
 public static void m3() throws FileNotFoundException{
   new FileInputStream("c:/ab.txt");
 }
}

捕捉   try...catch...

先来看看语法,

try{

可能出现异常的代码;

}catch(异常类型1 变量){

处理异常的代码;

}catch(异常类型2 变量){

处理异常的代码;

}......

看以下例子:

import java.io.*;
public class ExceptionTest05{
 public static void main(String[] args){
   try{
     //FileNotFoundException
     FileInputStream fis=new FileInputStream("c:/ab.txt");
   }catch(ArithmeticException e){  //捕获的异常是算术异常  
   }  
 }  
}

以上的代码编译无法通过,因为FileNotFoundException没有处理,报错:

ExceptionTest05.java:19: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
                        FileInputStream fis=new FileInputStream("c:/ab.txt");
                                           ^
1 个错误

也就是说可能出现异常的代码和捕获异常的代码必须是相对应的。

将捕获的异常修改之后,编译通过,

import java.io.*;
public class ExceptionTest05{
 public static void main(String[] args){
   try{
     //FileNotFoundException
     FileInputStream fis=new FileInputStream("c:/ab.txt");
   }catch(FileNotFoundException e){    
   }  
 }  
}

再看以下例子,以下程序编译无法通过,

import java.io.*;
public class ExceptionTest05{
 public static void main(String[] args){
   try{
     //FileNotFoundException
     FileInputStream fis=new FileInputStream("c:/ab.txt");
     fis.read();
   }catch(FileNotFoundException e){    
   }
 }  
}

报错:

ExceptionTest05.java:48: 错误: 未报告的异常错误IOException; 必须对其进行捕获或声明以便抛出
                        fis.read();
                               ^
1 个错误

因为read()方法又抛出了IOException的异常,而catch()只处理了FileNotFoundException的异常。

read()方法的抛出的异常如下图所示:

要想编译通过,必选进行IOException处理,

import java.io.*;
public class ExceptionTest05{
 public static void main(String[] args){
   try{
     //FileNotFoundException
     FileInputStream fis=new FileInputStream("c:/ab.txt");
     fis.read();
   }catch(FileNotFoundException e){    
   }catch(IOException e){
   }
 }  
}

或者如下直接进行IOException处理,这是因为FileNotFoundException继承IOException。

import java.io.*;
public class ExceptionTest05{
 public static void main(String[] args){
   try{
     //FileNotFoundException
     FileInputStream fis=new FileInputStream("c:/ab.txt");
     fis.read();
   }catch(IOException e){
   }
 }  
}

再看以下例子:

import java.io.*;
public class ExceptionTest05{
 public static void main(String[] args){
   try{
     //FileNotFoundException
     FileInputStream fis=new FileInputStream("c:/ab.txt");
     fis.read();
   }catch(IOException e){    
   }catch(FileNotFoundException e){
   }
 }  
}

编译出错:

ExceptionTest05.java:97: 错误: 已捕获到异常错误FileNotFoundException
               }catch(FileNotFoundException e){
                ^
1 个错误

这是因为FileNotFoundException继承IOException,catch语句块虽然可以写多个,但是从上到下catch,必须从小类型异常到大类型异常进行捕捉。并且try...catch...中最多执行一个catch语句块,执行结束后,try...catch...就执行结束了。

最后看一个详细的例子总结一下之前的内容。

import java.io.*;
public class ExceptionTest06{
 public static void main(String[] args){
   FileInputStream fis=new FileInputStream("abc");
   fis.read();
 }
}

以上程序编译无法通过,可以进行如下处理,

import java.io.*;
public class ExceptionTest06{
 public static void main(String[] args)throws IOException,FileNotFoundException{
   FileInputStream fis=new FileInputStream("c:/ab.txt");
   fis.read();
 }
}

或者进行如下处理:

import java.io.*;
public class ExceptionTest06{
 public static void main(String[] args)throws IOException{
   FileInputStream fis=new FileInputStream("c:/ab.txt");
   fis.read();
 }
}

或者使用try...catch...进行异常处理。

import java.io.*;
public class ExceptionTest06{
 public static void main(String[] args){
   try{
   FileInputStream fis=new FileInputStream("c:/ab.txt");
   fis.read();
   }catch(FileNotFoundException e){   //e内存地址指向的堆中的那个对象是FileNotFoundException类型的事件。
      System.out.println("读取的文件不存在!");
   }catch(IOException e){
     System.out.println("其它IO异常!");
   }
   System.out.println("ABC");
 }
}

运行之后输出:

读取的文件不存在!
ABC
 

如何取得异常对象的具体信息,常用的方法主要有两种:

取得异常信息描述:getMessage()

取得异常的堆栈信息(比较适合于程序调试阶段):printStackTrace();

先看取得异常的堆栈信息printStackTrace()方法。看以下例子。

import java.io.*;
public class ExceptionTest07{
 public static void main(String[] args){
   try{
     FileInputStream fis = new FileInputStream("c:/ab.txt");
   }catch(FileNotFoundException e){
     //打印异常堆栈信息
     //一般情况下都会使用该方式去调试程序
     e.printStackTrace();
   }
   //这段代码会执行
   System.out.println("ABC");
 }
}

编译运行后输出:

java.io.FileNotFoundException: c:\ab.txt (系统找不到指定的文件。)
       at java.io.FileInputStream.open0(Native Method)
       at java.io.FileInputStream.open(Unknown Source)
       at java.io.FileInputStream.<init>(Unknown Source)
       at java.io.FileInputStream.<init>(Unknown Source)
       at ExceptionTest07.main(ExceptionTest07.java:8)
ABC

再来看取得异常信息描述:getMessage()方法。

import java.io.*;
public class ExceptionTest07{
 public static void main(String[] args){
   try{
     FileInputStream fis = new FileInputStream("c:/ab.txt");
   }catch(FileNotFoundException e){
      msg=e.getMessage();
     System.out.println(msg);
   }
   System.out.println("ABC");
 }
}

编译运行后输出:

c:\ab.txt (系统找不到指定的文件。)
ABC

从上面的例子可以看出,e.printStackTrace()比e.getMessage()的方法详细,前者输出的异常信息比后者完整,因此一般使用e.printStackTrace()来打印异常信息。捕捉了异常之后进行打印才能知道你的代码哪里出现了异常,才能不断地去修改完善自己的代码,也就是所说的一般使用e.printStackTrace()去调试程序。

接下来再补充一下方法的重写与异常的知识。

这块儿内容只要记着一个原则:重写的方法不能比被重写的方法抛出更宽泛的异常。结合以下例子来理解一下。

class A{
 public void m1(){}
}
public class AB extends A{
 //子类永远无法比父类抛出更宽泛的异常
 public void m1() throws Exception{}
}

上述代码编译运行后出错:

AB.java:5: 错误: AB中的m1()无法覆盖A中的m1()
       public void m1() throws Exception{}
                   ^
 被覆盖的方法未抛出Exception
1 个错误

这是因为子类永远无法比父类抛出更宽泛的异常。再看一个例子:

import java.io.*;
class A{
 public void m1()throws FileNotFoundException{}
}
public class AB extends A{
 public void m1()throws IOException{}
}

编译运行后出错:

AB.java:22: 错误: AB中的m1()无法覆盖A中的m1()
       public void m1()throws IOException{}
                   ^
 被覆盖的方法未抛出IOException
1 个错误

父类中的m1()方法抛出FileNotFoundException异常,AB继承A,并且重写m1()方法,抛出IOException的异常,而我们知道,FileNotFoundException继承IOException,所以出错。

搜索微信公众号“程序员考拉”,欢迎关注!

 

Java 异常的处理方式--throws和try catch的更多相关文章

  1. “全栈2019”Java异常第九章:throws关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  2. java中的throw、throws和try catch浅析

    今天在公司和同事聊天的时候,突然发现自己对java中的throw.throws和try catch的作用理解不够准确,在网上查了查,在此大概梳理一下. throw用于抛出异常,例如 throw new ...

  3. java异常和throw和throws的区别

    之前在编程中编译完成后,运行时,会遇见一些常见的错误,如NullPointerException,ArrayIndexOutOfBoundsException等等 在今天重新回顾学习了java异常,总 ...

  4. JAVA异常及其异常处理方式

    异常处理 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的.比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error:如果你用Syste ...

  5. java异常中throw和throws的区别

    throws和throwthrows:用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁.  用在方法声明后面,跟的是异常类名  可以跟多个异常类名,用逗号隔开  表 ...

  6. java异常——五个关键字(try、catch、finally、throw、throws)

    一.try.catch.finally常用组合 try{ xxx }catch(xxxException e){ e.printStackTrace(); } try{ xxx }catch(xxxE ...

  7. “全栈2019”Java异常第八章:throw关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  8. Java异常题库

    一.填空题 __异常处理__机制是一种非常有用的辅助性程序设计方法.采用这种方法可以使得在程序设计时将程序的正常流程与错误处理分开,有利于代码的编写和维护. 在Java异常处理中可以使用多个catch ...

  9. Java异常之try,catch,finally,throw,throws

    Java异常之try,catch,finally,throw,throws 你能区分异常和错误吗? 我们每天上班,正常情况下可能30分钟就能到达.但是由于车多,人多,道路拥挤,致使我们要花费更多地时间 ...

随机推荐

  1. “全栈2019”Java第二十六章:流程控制语句中循环语句do-while

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  2. HDU6333-2018ACM暑假多校联合训练1002-Harvest of Apples-莫队+费马小定理

    题意很简单啦,求S(n,m)的值 通过打表我们可以知道 S(n + 1, m) = S(n, m) * 2 - C(n, m); S(n - 1, m) = (S(n, m) + C(n - 1, m ...

  3. 性能测试—JMeter 常用元件(二)

    性能测试—JMeter 常用元件(二) <零成本web性能测试>第三章 Web性能测试脚本录制与开发中JMeter常用测试元件 测试计划描述了JMeter运行时将会执行的一系列步骤,一个完 ...

  4. Levenshtein字符串距离算法介绍

    Levenshtein字符串距离算法介绍 文/开发部 Dimmacro KMP完全匹配算法和 Levenshtein相似度匹配算法是模糊查找匹配字符串中最经典的算法,配合近期技术栏目关于算法的探讨,上 ...

  5. SQL SERVER中的二种获得自增长ID的方法

    新方法 insert into TblClass output inserted.tClassId values('Hi~班','英语班') 老方法 insert into 表名 () values ...

  6. 使用Mondrian Virtual OLAP Cube 实现星座模型并在saiku展现分析

    1.什么是星座模型? 2.哪些地方可以用到星座模型? 3.Mondrian怎么构建星座模型,构建过程又涉及到哪些理论概念. 答1:这里描述了维度模型常用的 星型.雪花.星座模型,简而言之就是多事实表模 ...

  7. python全栈开发_day9_脚本文件和函数的基本运用

    一:脚本文件 1)脚本文件的操作 import sys p=sys.argv print(p) #将python代码放到cmd中运行,在后面添加参数,会自动保存在输出的列表中,默认输出的列表中只有一个 ...

  8. 高阶篇:4.2.4)DFMEA严重度S(+分类e)、频度O、探测度D、风险优先系数RPN

    本章目的:填写严重度S(+分类).频度O.探测度D,判定风险优先系数RPN. 1.前言 实施阶段中, 要求.潜在失效模式.潜在失效后果.潜在失效原因和现有设计控制措施等 5 个为基础项, 它们的分析是 ...

  9. Python Requests IP直连

    import re import requests from urllib3.util import connection _orig_create_connection = connection.c ...

  10. SpringCloud---声明式服务调用---Spring Cloud Feign

    1.概述 1.1 Spring Cloud Ribbon.Spring Cloud Hystrix的使用几乎是同时出现的,Spring Cloud提供了一个更高层次的封装这2个工具类框架:Spring ...