Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 316|回复: 0

Java 异常的处理方式--throws和try catch

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-8 05:21:09 | 显示全部楼层 |阅读模式

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

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

     

     
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-2 11:44 , Processed in 0.066202 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表