加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Java 异常的处理办法--throws和try catch

发布时间:2021-11-12 16:03:20 所属栏目:教程 来源:互联网
导读:异常的第一种处理方式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 FileIn

异常的第一种处理方式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,所以出错。

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读