zoukankan      html  css  js  c++  java
  • 《六》Java中的异常处理

    Java中的异常处理

    1.1异常概述

    在我们写的Java代码运行时产生的错误我们称之为--异常。异常分为二种一个是编译期异常(checked)、运行期异常(runtime)

    Examples:算术异常 java.lang.ArithmeticException

    public class Demo {
            public static void main(String[] args){
                int number = 3 / 0; 
            System.out.println(number);
        }
    }
    //Exception in thread "main" java.lang.ArithmeticException: / by zeat Demo.main(Demo.java:4)

    Examples: 空指针异常 java.lang.NullPointerException

    public class Demo {
            public static void main(String[] args){
                String str = null;
            System.out.println(str.toString());
        }
    }
    //Exception in thread "main" java.lang.NullPointerException at Demo.main(Demo.java:4)

    Examples: 数据类型转换异常 java.lang.NumberFormatException

    public class Demo {
            public static void main(String[] args){
                String str = "2.3"; 
            int number = Integer.parseInt(str);
            System.out.println(number);
        }
    }
    //Exception in thread "main" java.lang.NumberFormatException

    Examples: 对象强制类型转换异常

    public class Demo {
      public static void main(String[] args){
        Object o = new Test();
        String str = (String)o;
            System.out.println(str);
      }
    }
    class Test{}
    //Exception in thread "main" java.lang.ClassCastException

    Examples: 控制台输入的值与期望值不匹配

    import java.util.*;
    public class Demo{
      public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数值:");
        int number = input.nextInt();
        System.out.println(number);
      }
    }
    //运行代码,输入一个非数值
    //InputMismatchException

    1.2 捕捉处理异常

    在Java代码中,使用try-catch-finally代码块来进玍捕捉异常。

    try {
     //程序代码块 
    } catch(Exceptiontype e) {
      //对Exceptiontype的处理
    } finally {
      //无论如何都要执行的代码块
    }

    分析:

    1. try中的程序代码块指的是可能会产生异常的代码;

    2. catch中的Exceptiontype的作用是捕捉并处理与已产生的异常类型相匹配的异常对象e;

    3. finally中的代码埠是异常处理过程中最后被执行的部分,无论程序是否产生异常,finally中的代码块都将被执行。

    Examples: 使用try-catch来演示顾客买东西付款场景

    public public class class Demo {Demo {
            public public static static void void main(main(String[] String[] args){args){
                    try {try {
                    String String message message = = "西瓜:3.99元/500克";"西瓜:3.99元/500克";
                    //使用:分割字符串,方便得到单价//使用:分割字符串,方便得到单价
                    String[] String[] strArr strArr = = message.message.split(split(":");":");
                    
                    //单价//单价
                    double double price price = = Double.Double.parseDouble(parseDouble(strArr[strArr[2].2].substring(substring(0, 0, 4));4));
                    double double weight weight = = 1878; 1878; //西瓜重量//西瓜重量
                    //计算总价格//计算总价格
                    System.System.out.out.println((println((float)(float)(weight weight / / 500 500 * * price) price) + + "元");"元");
          }       } catch(catch(Exception Exception e){e){
                            e.e.printStackTrace();printStackTrace();
          }      }
            
                    System.System.out.out.println(println("结束");"结束");
      }  }
    }}
    //java.lang.ArrayIndexOutOfBoundsException//java.lang.ArrayIndexOu
    //结束
    注意: 代码产生异常,不会影响程序的执行。「printStackTrace() =>输出异常信息」、「getMessage()=>获得有关异常事件的信息」、「toString()=>获得异常的类型与性质」
    
    Examples: 多个catch代码块一起使用
    
    public class Demo {
            public static void main(String[] args){
                try {
              String message = "西瓜:3.99元/500克";
              //使用:分割字符串,方便得到单价
              String[] strArr = message.split(":");
    ​
              //单价
              double price = Double.parseDouble(strArr[2].substring(0, 4));
              double weight = 1878; //西瓜重量
              //计算总价格
              System.out.println((float)(weight / 500 * price) + "元");
            }catch(ArrayIndexOutOfBoundsException ex){
                    ex.printStackTrace();
            }catch(Exception e){
                    e.printStackTrace();
            }
            System.out.println("结束");
        }
    }
     
    
    注意: 在使用异常处理方法时,关于多个catch使用一定要知道先子类后父类。父类是Exception
    
    public class Demo {
            public static void main(String[] args){
                int number[] = {1,2,3,4};
          
              for(int i = 0; i < 5; i++){
                    try {
                        System.out.println("当 i = " + i + "," + i + " < 5 时,a[" + i + "] = " + a[i] + ";"); 
                }catch(ArrayIndexOutBoundsException e){
                        System.out.println(e.toString());
                      e.printStackTrace();
                      System.out.println("超出数组索引");
                }
            }
        }
    }
    import java.util.*;
    
    public class Demo {
            public static void main(String[] args){
                  Scanner input = new Scanner(System.in);
                  try {
                      System.out.println("请输入第一个整数:");
                                int num1 = input.nextInt();
                    
                    System.out.println("请输入一个运算符(+-*/)");
                                String sym = input.next();
                
                    System.out.println("请输入第二个整数:");
                                int num2 = input.nextInt();
                
                    int result = 0;
                  switch(sym){
                    case "*":
                      result = num1 * num2;
                      break;
                    case "-":
                      result = num1 - num2;
                      break;
                    case "/":
                      result = num1 / num2;
                      break;
                    case "+":
                      result = num1 + num2;
                      break;
                  }
                  System.out.println("result=" + result);
                        } catch(InputMismatchException e){
                    e.printStackTrace();
                        }            
            }      
    }  

    1.3 finally 代码块

    完整的异常处理语句应该包含finally代码块,finally代码块在程序中有无异常产生,finally代码块中的代码都会被执行。

    import java.util.*;
    
    public class Demo {
            public static void main(String[] args){
                Scanner input = new Scanner(System.in);
              System.out.println("西瓜单位(格式为:2.99):");
              String strPrice = input.next();
              //判断长度是否等于4
              if (strPrice.length() == 4){
                  try{
                      String message = "西瓜:" + strPrice + "元/500克";
                      String[] strArr = message.split(":");
                      String tmpPrice = strArr[2].substring(0,4);
                      double weight = 789;
                      double price = Double.parseDouble(tmpPrice);
                  
                      System.out.println("总额为:" + (float)(weight / 500) * price + "元");
                }catch(ArrayIndexOutOfBoundsException ex){
                      //打印异常信息
                      ex.printStackTrace();
                }finally{
                      input.close();
                      System.out.println("窗口程序关闭");
                }
                    }else{
                     System.out.println("输入价格有误!");
            }
            }
    }  
    //输入3.99
    //java.lang.ArrayIndexOutOfBoundsException: 2
    //窗口程序关闭

    分析:使用try-catch出现异常不会立马终止程序,代码会执行catch代码块,上面示例中会执行finnaly代码块。

     

    Examples:模拟银行取款

    import java.util.*;
    
    public class Demo {
          public static void main(String[] args){
          double money = 14903.48; //账号默认金额
          Scanner input = new Scanner(System.in);
          System.out.println("请输入取款金额:");
          try{
            int outMoney = input.nextInt();
            double result = money - outMoney;
            if(result >= 0){
                System.out.println("余额:" + (float)result + "元");
            }else{
              System.out.println("余额不足");
            }
          }catch(InputMismatchException e){
            e.printStackTrace();
          }finally{
            input.close(); //关闭窗口程序
          }
        }
    }

    1.4 在方法中抛出异常

    在上面的学习中,关于异常我们可以接经catch代码块来处理。但是在Java代码中,对于产生的异常,并不想处理这个异常,那么我们就可以使用throws和throw关键字来进行抛出。

    1.4.1 使用throws关键字抛出异常

    throw关键字一般被应用于方法上,表示方法可能会抛出异常;当方法抛出多个异常时,可用逗号分隔异常类型名。

    返回值类型名 方法 (参数列表) throws 异常类型名 {
      方法体
    }
    public class Demo {
      public static void main(String[] args){
        try{
          Demo d = new Demo();
          d.say();
        }catch(ArrayIndexOutOfBoundsException e){
          e.printStackTrace();
        }
      }
      public void say() throws ArrayIndexOutOfBoundsException{
        String[] strArr = {"你好吗?", "来吧"};
        System.out.println(strArr[2]);
      }
    }
    //java.lang.ArrayIndexOutOfBoundsException: 2

    多个异常抛出

    public class Demo{
      public static void main(String[] args){
        try{
          Demo d = new Demo();
          d.say();
        }catch(ArrayIndexOutOfBoundsException e){
          System.out.println("ArrayIndexOutOfBoundsException");
        }catch(NullPointerException n){
          System.out.println("NullPointerException");
        }
      }
      public void say() throws ArrayIndexOutOfBoundsException,NullPointerException{
        String[] strArr = {"你好吗?", "来吧"};
        System.out.println(strArr[2]);
        String tmp = null;
        System.out.println(tmp.toString());
      }
    }

    1.4.2 使用throw关键字抛出异常

    在Java程序出现错误时,系统会自动抛出异常;除此之外,可使用关键字throw自行抛出异常。在使用throw自行抛出异常时,throw语句抛出的不是异常类,而是异常实例,而且每次只能抛出一个异常实例。

    throw new 异常类型名(异常信息)
    public class Demo {
      public static void main(String[] args){
        try{
          throwChecked(-1);
        }catch(Exception e){
          System.out.println(e.getMessage());
        }
        throwRuntime(3);
      }
      
      //必须要在try-catch代码块里,或者在带有throws声明的方法中
      public static void throwChecked(int a) throws Exception{
        if(i > 0){
          throw new Exception("a的值大于0");
        }
      }
      
      public static void throwRuntime(int a){
        if(i > 0){
          throw new RuntimeException("a的值大于0");
        }
      }
    }
    
    //Exception in thread "main" java.lang.RuntimeException: a的会上大于0

    1.4.3 自定义异常类

    通俗的理解就是创建自己定义的异常类,但是自定义异常类通常需要提供两种构造器:一个是无参数的构造器;另一个是带一个字符串参数的构造器。

    class CustomException extends Exception {
      public CustomException(){}
      
      public CustomException(String message){
        super(message);
      }
    }
    
    public class Demo {
      public static void main(String[] args){
        try{
          Demo d = new Demo();
            d.say();
        }catch(CustomException e){
          System.out.println(e.getmessage());
        }
      }
      public void say() throws CustomException{
        throw new CustomException("我是自定义的异常类customException");
      }
    }

    1.4.4 catch和throw同时使用

    class AuctionException extends Exception{
      public AuctionException(String message){
        super(message);
      }
    }
    
    public class Demo{
      private double number = 40.0;
      public static void main(String[] args){
        try{
          Demo d = new Demo();
          d.say("aa");
        }catch(AuctionException e){
          System.err.println(e.getMessage());
        }
      }
      
      public void say(String str) throws AuctionException{
        try{
          double num = Double.parseDouble(str);
        }catch(Exception e){
          e.printStackTrace();
          throw new AuctionException("只能是数字");
        }
      }
      if(number < num){
        throw new AuctionException("不于小于" + number);
      }
    }

    1.4.5 throws关键字和throw关键字的区别

    1. throws用在方法声明后面,表示抛出异常,由方法的调用者处理,而throw用在方法体内,同来制造一个异常,由方法体内的语句处理

    2. throws是声明这个方法会抛出这种类型的异常,方便调用者知道要捕捉这个异常,而throw是直接抛出一个异常实例

    3. throws表示出现异常的一种可能性,并不一定会产生这些异常,如果直接使用throw,就一定会产生某种异常

  • 相关阅读:
    梅特卡夫法则(Metcalfe's law)
    jffs2reset 实现分析
    uhttpd配置文件分析
    疑问????
    ubuntu 修改root密码
    原始套接字
    位操作
    linux命令readlink
    awk 中 FS的用法
    Python做简单爬虫(urllib.request怎么抓取https以及伪装浏览器访问的方法)
  • 原文地址:https://www.cnblogs.com/beimingdaoren/p/13161352.html
Copyright © 2011-2022 走看看