异常的捕获和处理

异常的捕获和处理

  1. package org.forten.demo;
    
    import java.io.IOException;
    import java.sql.SQLException;
    import java.util.Random;
    
    public class ExceptionDemo001 {
     private Random random = new Random();
     
     
     //在方法参数列表的圆括号后跟throws关键字
     //throws声明了此方法在被调用后可能会抛出异常类型
     //多个异常类型使用逗号分隔
     //通知调用方,此方法的运行可能会出现那些问题,请调用方及时处理
     public void test1() throws IOException, SQLException {
         if (random.nextBoolean()) {
         //throw关键字的功能是抛出某个类型的异常对象
         //抛出给调用此方法的客户程序(调用此方法的另一段代码)
         //当方法抛出异常后,程序就执行结束了(程序异常结束)
         //throw相对于return,也是一种程序执行的出口
         throw new IOException("磁盘输入输出异常——受检异常");
         } else {
             throw new SQLException("数据库操作异常——受检异常");
         }
    }
         //当在一个方法中调用另一个声明了有可能会抛出受检异常的方法时,这个方法也要对那些受检异常进行处理
         //处理方式有两种:
         //1. 再次抛出这些异常(击鼓传花,在invoke()方法中不能处理或没必要处理test1()所抛出的异常,可以直接再次把这些异常抛出给invoke()方法的调用方)
         //2. 内部处理(把异常对象在invoke1()方法内部消除或转化掉)
         //在invoke1()中调用了抛出受检异常的test1(),在invoke1()中使用了再次抛出的方式进行异常处理
         public void invoke1() throws IOException, SQLException {
         test1();
     }
         //此方法在运行过程中会抛出Error或RuntimeException类型的异常
         //但它们属于非受检的,一般程序员不能解决或必须解决的问题所导致的
         //所以可以不进行对着两类错误或异常的显式处理
         public void test2() throws Error, RuntimeException {
         if (random.nextBoolean()) {
             throw new Error("系统灾难-非受检");
         } else {
             throw new RuntimeException("运行时异常-非受检");
         }
     }
    
     public void invoke2() {
         test2();
     }
     
     public static void main(String[] args) throws IOException, SQLException {
         ExceptionDemo001 ed = new ExceptionDemo001();
            //在invoke()的执行中,一定会抛出SQLException或IOException异常对象中的一个
            //而当有异常抛出到JVM后,程序就会直接结束,后续代码不会继续执行
            ed.invoke1();//异常发生,程序结束
            //以下语句不会被执行
            ed.invoke2();
     }
    }
    
            
    
  2. package org.forten.demo;
    
    import java.io.IOException;
    import java.sql.SQLException;
    import java.util.Random;
    
    public class ExceptionDemo002 {
     private Random random = new Random();
    
     public void test1() throws IOException, SQLException {
         if (random.nextBoolean()) {
             throw new IOException("磁盘输入输出异常——受检异常");
         } else {
             throw new SQLException("数据库操作异常——受检异常");
         }
     }
    
     public void test2() throws Error, RuntimeException {
         if (random.nextBoolean()) {
             throw new Error("系统灾难-非受检");
         } else {
             throw new RuntimeException("运行时异常-非受检");
         }
     }
    
     public static void main(String[] args) {
         ExceptionDemo002 de = new ExceptionDemo002();
         // de.test2();
         
         
         //catch块和finally块是可选的,但必须依赖于try块的存在
         try{
         尝试执行的代码(有可能会抛出异常)
         }catch(IOException e){
         在运行try中的代码时,捕获到IOException异常对象,则执行此代码块中的逻辑
         }catch(SQLException e){
         在运行try中的代码时,捕获到SQLException异常对象,则执行此代码块中的逻辑
         }finally{
         无论在try块中是否抛出异常,都会执行此代码块中的逻辑。通常此处编写释放系统资源的代码
         }
         
         //最佳实践:在catch块中一定要写一些与异常或错误相关程序逻辑(哪怕时打印错误)
         //如果出现空catch块,则是一种极其恶劣的编码习惯
         try {
             de.test1();
         } catch (IOException e) {
             e.printStackTrace();
         } catch (SQLException e) {
             System.out.println(e.getMessage());
         } finally {
             System.out.println("必定执行的代码块");
         }
         
         
         //以下语句是可以被执行的
         //以为本方法处理异常的方式是内部化解,虽然出现了程序异常,但被处理掉了
         //程序可以继续执行
         System,out.println("执行完成");
         }
    }
         
    
  3. package org.forten.demo;
    
    import java.io.IOException;
    import java.nio.charset.CharacterCodingException;
    import java.sql.SQLException;
    import java.util.Random;
    
    public class ExceptionDemo003 {
     private Random random = new Random();
    
     public void test() throws IOException, SQLException, CharacterCodingException, ClassNotFoundException, Exception {
         int n = random.nextInt(6);
         System.out.println(n);
         switch (n) {
         case 1:
             throw new IOException();
         case 2:
             throw new SQLException();
         case 3:
             throw new CharacterCodingException();
         case 4:
             throw new ClassNotFoundException();
         case 5:
             throw new Exception();
         default:
             System.out.println("正确执行完成");
         }
     }
    
     public static void main(String[] args) {
         ExceptionDemo003 ed = new ExceptionDemo003();
         //在捕获多个异常对象时,应该把最特殊的异常类的catch块放在前面
         //相对更一般的异常类catch块放在后面
         //否则会得到不可到达的编译错误
         //因为更特殊的异常会自动向上转型成为更一般的异常类型,如果先捕获一般的异常,也会包含着不捕获了特殊异常
         //所以特殊异常的catch块就不可达了
         //异常子类在前被捕获,异常父类在后被捕获(子类在前,父类在后)
         
         
         //Java 7 以前的版本(不包含Java 7)每一个catch块只能处理一种异常
         //Java 7以后有所变化,请看下一个例子
         try {
             ed.test();
         } catch (CharacterCodingException e) {
             e.printStackTrace();
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } catch (SQLException e) {
             e.printStackTrace();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    }
    
    
  4. package org.forten.demo;
    
    import java.io.IOException;
    import java.nio.charset.CharacterCodingException;
    import java.sql.SQLException;
    import java.util.Random;
    
    public class ExceptionDemo004 {
     private Random random = new Random();
    
     public void test() throws IOException, SQLException, CharacterCodingException, ClassNotFoundException, Exception {
         int n = random.nextInt(6);
         System.out.println(n);
         switch (n) {
         case 1:
             throw new IOException();
         case 2:
             throw new SQLException();
         case 3:
             throw new CharacterCodingException();
         case 4:
             throw new ClassNotFoundException();
         case 5:
             throw new Exception();
         default:
             System.out.println("正确执行完成");
         }
     }
    
     public static void main(String[] args) {
         ExceptionDemo004 ed = new ExceptionDemo004();
         //Java 7以后引入的多异常对象同时捕获,可以在一个catch块中捕获多种异常类型对象
         //语法:catch(异常类型1|异常类型2|...异常类型n   e){}其中e为某种异常对象的引用变量
         //e的具体类型取决于运行时此catch块捕获到的异常类型
         //其异常的捕获顺序还是从特殊到一般的,同一继承层次的异常类型,建议放在一个圆括号内
         //处理更具体地异常类型地catch块应该放在前面,更抽象地异常类型catch块应该放在后边
         //在同一个圆括号中的多个异常类不能时父子关系(祖先后代关系)
         try {
             ed.test();
         } catch (CharacterCodingException e) {
             e.printStackTrace();
         } catch (IOException | SQLException | ClassNotFoundException e) {
             e.printStackTrace();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    }
    
  5. package org.forten.demo;
    //使用异常的原则:早抛出,晚捕获
    //只有在必须处理异常的时候采取try-cathc-finally,一般情况下使用throws抛出
    public class ExceptionDemo005 {
     public static void test() {
         throw new MyException("自定义的异常被抛出了......");
     }
    
     public static void main(String[] args) {
         try {
             test();
         } catch (MyException e) {
             System.out.println(e.getErrorTime());
             System.out.println(e.getMessage());
             e.printStackTrace();
         }
     }
    }
    
    
  6. package org.forten.demo;
    
    public class ExceptionTest001 {
     public static int test() {
         int a = 10;
         //finally 块一定会执行
         //如果在catch中存在return语句,也要在执行finally块之后才会执行返回
         //但返回的数据会在执行finally之前被挂起
         try {
             a = 20;
             if(true) {
                 throw new RuntimeException();
             }
         } catch (RuntimeException e) {
             a = 30;
             return a;// return 30;
         } finally {
             a = 40;
             // return a;
         }
         return a;
     }
     
     public static void main(String[] args) {
         System.out.println(test());
     }
    }
    
  7. package org.forten.demo;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Objects;
    
    public class MyException extends RuntimeException {
     private static final long serialVersionUID = -3116864107074972818L;
    
     private Date errorTime;
     private static final SimpleDateFormat sdf = new SimpleDateFormat("[yyyy年MM月dd日 HH:mm:ss SSS]");
    
     public MyException() {
         this("发生了MyException");
     }
    
     public MyException(String message) {
         super(message);
         this.errorTime = new Date();
     }
    
     public Date getErrorTime() {
         return this.errorTime;
     }
    
     @Override
     public String getMessage() {
         return sdf.format(Objects.requireNonNullElse(errorTime, new Date())) + super.getMessage();
     }
    }
    
    
  8. ackage org.forten.io.file;
    
    import java.io.File;
    import java.io.IOException;
    //java.io.File
    //以上的File类是Java中对磁盘文件和目录(文件夹)的抽象
    public class FileDemo001 {
     public static void main(String[] args) throws IOException {
         // File file1 = new File("f:\\test");
         // File file1 = new File("f:"+File.separator+"test");
         File file1 = new File("f:/test");
         System.out.println("file1.mkdir(): " + file1.mkdir());
         
         File file2 = new File("f:/aaa/bbb/ccc/ddd");
         System.out.println("file2.mkdirs(): " + file2.mkdirs());
         
         File file3 = new File("f:/test.txt");
         System.out.println("file3.createNewFile() " + file3.createNewFile());
     }
    }
    
    

你可能感兴趣的:(异常的捕获和处理)