异常的体系
java异常的种类
运行时异常:RuntimeException
及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如: 数组索引越界异常
编译时异常:编译阶段就会出现错误提醒的。(如:日期解析异常)
我们在调用SimpleDateFormat
对象的parse方法时,要求传递的参数必须和指定的日期格式一致,否则就会出现异常。 Java比较贴心,它为了更加强烈的提醒方法的调用者,设计了编译时异常,它把异常的提醒提前了,你调用方法是否真的有问题,只要可能有问题就给你报出异常提示(红色波浪线)。
编译时异常的目的:注意!!这里小心点容易出错,仔细检查一下
确认代码没问题,为了让它不报错,继续将代码写下去。这里有两种解决方案。
- 第一种:使用throws在方法上声明,意思就是告诉下一个调用者,这里面可能有异常啊,你调用时注意一下。
1 2 3 4 5 6 7 8 9 10
|
public class ExceptionTest1 { public static void main(String[] args) throws ParseException{ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = sdf.parse("2028-11-11 10:24"); System.out.println(d); } }
|
- 第二种:使用try…catch语句块异常进行处理。
1 2 3 4 5 6 7 8 9 10 11
| public class ExceptionTest1 { public static void main(String[] args) throws ParseException{ try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = sdf.parse("2028-11-11 10:24"); System.out.println(d); } catch (ParseException e) { e.printStackTrace(); } } }
|
自定义异常
如果企业自己的某种问题,想通过异常来表示,那就需要自己来定义异常类了。
自定义异常的种类
自定义运行时异常
- 定义一个异常类继承
RuntimeException
.
- 重写构造器。
- 通过
throw new 异常类(xxx)
来创建异常对象并抛出。编译阶段不报错,提醒不强烈,运行时才可能出现!
自定义编译时异常
- 定义一个异常类继承
Exception
.
- 重写构造器。
- 通过
throw new 异常类(xxx)
来创建异常对象并抛出。编译阶段就报错,提醒更加强烈!
示例需求:写一个saveAge(int age)
方法,在方法中对参数age进行判断,如果age<0或者>=150就认为年龄不合法,如果年龄不合法,就给调用者抛出一个年龄非法异常。
分析:Java的API中是没有年龄非常这个异常的,所以我们可以自定义一个异常类,用来表示年龄非法异常,然后再方法中抛出自定义异常即可。
- 先写一个异常类
AgeIllegalException
(这是自己取的名字,名字取得很奈斯),继承
1 2 3 4 5 6 7 8 9
| public class AgeIllegalException extends Exception{ public AgeIllegalException() { }
public AgeIllegalException(String message) { super(message); } }
|
- 再写一个测试类,在测试类中定义一个
saveAge(int age)
方法,对age判断如果年龄不在0~150之间,就抛出一个AgeIllegalException
异常对象给调用者。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class ExceptionTest2 { public static void main(String[] args) { try { saveAge2(225); System.out.println("saveAge2底层执行是成功的!"); } catch (AgeIllegalException e) { e.printStackTrace(); System.out.println("saveAge2底层执行是出现bug的!"); } }
public static void saveAge(int age){ if(age > 0 && age < 150){ System.out.println("年龄被成功保存: " + age); }else { throw new AgeIllegalRuntimeException("/age is illegal, your age is " + age); } } }
|
注意咯,自定义异常可能是编译时异常,也可以是运行时异常
如果自定义异常类继承Excpetion
,则是编译时异常。
- 特点:方法中抛出的是编译时异常,必须在方法上使用
throws
声明,强制调用者处理。
如果自定义异常类继承RuntimeException
,则运行时异常。
- 特点:方法中抛出的是运行时异常,不需要在方法上用
throws
声明。
异常处理
开发中对于异常的常见处理方式
- 捕获异常,记录异常并响应合适的信息给用户
- 捕获异常,尝试重新修复
我们看一个代码,main方法调用test1方法,test1方法调用test2方法,test1和test2方法中多有扔异常。
- 第一种处理方式是,在main方法中对异常进行try…catch捕获处理了,给出友好提示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class ExceptionTest3 { public static void main(String[] args) { try { test1(); } catch (FileNotFoundException e) { System.out.println("您要找的文件不存在!!"); e.printStackTrace(); } catch (ParseException e) { System.out.println("您要解析的时间有问题了!"); e.printStackTrace(); } }
public static void test1() throws FileNotFoundException, ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = sdf.parse("2028-11-11 10:24:11"); System.out.println(d); test2(); }
public static void test2() throws FileNotFoundException { InputStream is = new FileInputStream("D:/meinv.png"); } }
|
- 第二种处理方式是:在main方法中对异常进行捕获,并尝试修复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
public class ExceptionTest4 { public static void main(String[] args) { while (true) { try { System.out.println(getMoney()); break; } catch (Exception e) { System.out.println("请您输入合法的数字!!"); } } }
public static double getMoney(){ Scanner sc = new Scanner(System.in); while (true) { System.out.println("请您输入合适的价格:"); double money = sc.nextDouble(); if(money >= 0){ return money; }else { System.out.println("您输入的价格是不合适的!"); } } } }
|
链接
封面图来源:https://www.pixiv.net/artworks/97756295