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 { //无论如何都要执行的代码块 }
分析:
-
try中的程序代码块指的是可能会产生异常的代码;
-
catch中的Exceptiontype的作用是捕捉并处理与已产生的异常类型相匹配的异常对象e;
-
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关键字的区别
-
throws用在方法声明后面,表示抛出异常,由方法的调用者处理,而throw用在方法体内,同来制造一个异常,由方法体内的语句处理
-
throws是声明这个方法会抛出这种类型的异常,方便调用者知道要捕捉这个异常,而throw是直接抛出一个异常实例
-