《六》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,就一定会产生某种异常

posted on 2020-06-19 09:29  北冥道人骑鲲打代码  阅读(257)  评论(0编辑  收藏  举报

导航