异常是指程序在"编译"或者"执行"过程中可能出现的问题
注意:语法错误不算在异常体系中
异常体系结构
Java中的异常主要是继承自 Throwable类,分为 Error 和 Exception.
Error : 是系统级别错误,JVM退出等,代码无法控制
Exception:编译时异常 ---- 除了RuntimeException及其子类以外的异常运行时异常 ---- RuntimeException
注意:运行时异常一般是程序员业务没有考虑好或者逻辑不严谨引起的程序错误
int[] arr = {1,2,3};System.out.println(arr[0]);System.out.println(arr[1]);System.out.println(arr[2]);//System.out.println(arr[3]); 数组索引越界异常 ArrayIndexOutOfBoundsException
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3at ptionDemo.main(exceptionDemo.java:10)
String str = null;System.out.println(str); // 可以输出 但是不能调用方法//System.out.println(str.length());
Exception in thread "main" java.lang.NullPointerExceptionat ptionDemo.main(exceptionDemo.java:15)
int a = 10;int b = 0;System.out.println(a / b);
Exception in thread "main" java.lang.ArithmeticException: / by zeroat ptionDemo.main(exceptionDemo.java:20)
Object o = 123; // Object一切类的祖宗类 什么样的类型都可以接收String str1 = (String) o; // 123整数类型无法转换成String
Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')at ptionDemo.main(exceptionDemo.java:24)
//数字转换异常 NumberFormatExceptionString str2 = "124aaa";Integer in = Integer.valueOf(str2);System.out.println(in + 1);
Exception in thread "main" java.lang.NumberFormatException: For input string: "124aaa"at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)at java.base/java.lang.Integer.parseInt(Integer.java:658)at java.base/java.lang.Integer.valueOf(Integer.java:989)at ptionDemo.main(exceptionDemo.java:28)
不是RuntimeException或者其子类的异常, 编译时就报错,必须处理,否则代码不通过
//编译时异常案例String date = "2020-11-11 11:11:11";SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss"); //故意把格式写错 看异常提示信息Date d = sdf.parse(date);System.out.println(d);
其中
Date d = sdf.parse(date)会有日期解析异常,ParseException
Exception in thread "main" ParseException: Unparseable date: "2020-11-11 11:11:11"at java.DateFormat.parse(DateFormat.java:395)at ptionDemo2.main(exceptionDemo2.java:14)
1.默认会在出现异常的代码那里自动的创建一个异常对象2.异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给虚拟机3.虚拟机接收异常对象后,先在控制台直接输出异常栈信息数据4.直接从当前执行的异常点结束当前程序5.后续代码没有机会执行,因为程序已经死亡
案例
System.out.println("程序开始");int a = 10;int b = 0;chu(a,b);System.out.println("程序结束");}public static void chu(int a,int b){System.out.println(a);System.out.println(b);System.out.println(a / b);}
程序开始
10
0
Exception in thread "main" java.lang.ArithmeticException: / by zeroat ptionDemo3.chu(exceptionDemo3.java:16)at ptionDemo3.main(exceptionDemo3.java:9)
编译时异常是编译阶段就出错的,所以必须处理,否则代码无法通过
方式1
出现异常直接抛出去给调用者,调用者也继续抛出去
方式2
出现异常自己捕获处理,不麻烦别
方式3
前两者结合,出现异常直接抛出去给调用者,调用者捕获处理
抛出异常格式:方法 throws 异常1,异常2,异常3...{}规范做法:方法 throws Exception{}
/*演示异常处理方式一 : throws*/public static void main(String[] args) throws ParseException {String date = "2011-11-11 11:11:11";System.out.println("程序开始~~");ParseTime(date);System.out.println("程序结束~~");}public static void ParseTime(String date) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date d = sdf.parse(date);System.out.println(d);}
正常执行:程序开始~~
Fri Nov 11 11:11:11 CST 2011
程序结束~~发生异常:(这里将异常对象抛给了JVM虚拟机 虚拟机会打印错误信息 然后结束掉当前程序 后面的程序就不再执行了)程序开始~~
Exception in thread "main" ParseException: Unparseable date: "2011-11-11 11:11:11"at java.DateFormat.parse(DateFormat.java:395)at ptionThrows.ParseTime(exceptionThrows.java:21)at ptionThrows.main(exceptionThrows.java:15)
如果程序下面还有异常抛出,可以在方法后面继续抛出更多的错误
public static void ParseTime(String date) throws ParseException, FileNotFoundException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");Date d = sdf.parse(date);System.out.println(d);InputStream in = new FileInputStream("E:/apple.jpg");}
后面的读取文件也可能出现错误,所以在方法的后面也抛出了FileNotFoundException异常注意:
因为前面的日期解析已经抛出异常了,所以后面的异常就没有机会抛出,因为前面异常抛出被JVM虚拟机接收以后,程序就已经结束了,后面的程序没有机会再执行.
这里有个问题,如果程序里面需要抛出的异常对象很多,那么就会在方法后面写一大堆异常对象,这样显得累赘臃肿
推荐格式
public static void ParseTime(String date) throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");Date d = sdf.parse(date);System.out.println(d);InputStream in = new FileInputStream("E:/apple.jpg");}
直接在方法后面加上 throws Exception即可
格式:
try{//监视可能出现异常的代码}catch(异常类型1 变量){//处理异常
}catch(异常类型2 变量){//处理异常
}...建议格式:try{//可能出现问题的代码
}catch(Exception e){e.printStackTrace(); //直接打印异常栈信息
}Exception可以捕获一切异常类型
public static void ParseTime(String date) {try {SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");Date d = sdf.parse(date);System.out.println(d);InputStream in = new FileInputStream("E:/apple.jpg");} catch (ParseException | FileNotFoundException e) {e.printStackTrace();}//直接 catch (Exception e)/* catch (Exception e) {e.printStackTrace();} */}
String date = "2011-11-11 11:11:11";System.out.println("程序开始~~");try {ParseTime(date);} catch (Exception e) {e.printStackTrace();}System.out.println("程序结束~~");}public static void ParseTime(String date) throws Exception{SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");Date d = sdf.parse(date);System.out.println(d);InputStream in = new FileInputStream("E:/apple.jpg");}
在ParseTime方法中采用抛出异常的方式,调用者在主函数中接收抛出的异常捕获并处理.采用语句
public static void main(String[] args) {System.out.println("程序开始");int a = 10;int b = 0;try {chu(a,b);System.out.println("程序结束");} catch (Exception e) {e.printStackTrace();System.out.println("操作失败");}}public static void chu(int a,int b){System.out.println(a);System.out.println(b);System.out.println(a / b);}
程序开始
10
0
操作失败
java.lang.ArithmeticException: / by zeroat ption_hadle_runtime.chu(exception_hadle_runtime.java:21)at ption_hadle_runtime.main(exception_hadle_runtime.java:10)
案例:
需求:键盘录入一个合理的价格为止(必须是数值,值必须大于0)
Scanner sc = new Scanner(System.in);while (true) {try {System.out.println("请输入价格:");String priceStr = sc.nextLine();//转换成double类型double d = Double.valueOf(priceStr);if (d > 0) {System.out.println("定价是:" + d);break;} else {System.out.println("价格不能为负数 请重新输入~");}} catch (NumberFormatException e) {System.out.println("输入有问题 不能乱搞啊 ~~~~");}}
在没有添加try catch语句时候,如果键盘录入了非法字符,程序就会异常终止掉.
当添加了try catch语句,当键盘再次录入不合法数据时,就可以在异常语句中给到提醒并再次录入,直到录入成功为止
如此一来,保证了程序的稳健性.
第一步 : 定义一个异常类继承Exception
第二步 : 重写构造器
第三步 : 在出现异常的地方用 throw new 自定义对象抛出
public class AgeIllegalException extends Exception{/*自定义 编译时异常 AgeIllegalException1.继承Exception2.重写构造器年龄超过200 或者 小于0 就是异常*/public AgeIllegalException() {}public AgeIllegalException(String message) {super(message);}}
public class DIYDemo {public static void main(String[] args) throws AgeIllegalException {checkAge(900);}public static void checkAge(int age) throws AgeIllegalException {if (age < 0 || age > 200){//throws: 用在方法申明上的,抛出方法内部的异常//throw:在方法内部直接创建一个异常对象,并从此点抛出// 抛出去一个异常对象给调用者throw new AgeIllegalException(age+" is illegal");}else{System.out.println("年龄合法 推荐相应商品");}}
}
Exception in thread "main" d1_exceptiom_DIY.AgeIllegalException: 900 is illegalat d1_exceptiom_DIY.DIYDemo.checkAge(DIYDemo.java:17)at d1_exceptiom_DIY.DIYDemo.main(DIYDemo.java:6)
第一步 : 自定义一个异常类继承RuntimeException
第二步 : 重写构造器
第三步 : 在出现异常的地方用 throw new 自定义对象抛出作用 : 提醒不强烈,编译阶段不报错!!! 运行时才可能出现!
public class AgeIlleagalRuntimeException extends RuntimeException {public AgeIlleagalRuntimeException() {}public AgeIlleagalRuntimeException(String message) {super(message);}
}
public class DIYDemo {public static void main(String[] args) {try {checkAge(900);} catch (Exception e) {e.printStackTrace();}checkAge(23);}public static void checkAge(int age) {if (age < 0 || age > 200){//throws: 用在方法申明上的,抛出方法内部的异常//throw:在方法内部直接创建一个异常对象,并从此点抛出// 抛出去一个异常对象给调用者throw new AgeIlleagalRuntimeException(age+" is illegal");}else{System.out.println("年龄合法 推荐相应商品");}}
}
d1_exceptiom_DIY.AgeIlleagalRuntimeException: 900 is illegalat d1_exceptiom_DIY.DIYDemo.checkAge(DIYDemo.java:24)at d1_exceptiom_DIY.DIYDemo.main(DIYDemo.java:7)
年龄合法 推荐相应商品
本文发布于:2024-02-03 04:29:08,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170690574648652.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |