目录
认识异常
介绍
什么是异常?
- 异常就是代表程序出现的问题。
比如:
int[] arr = {10,20,30};
System.out.println(arr[3]);
System.out.println(10 / 0);
运行之后会报错,以一个异常对象抛出来错误。
异常的体系
Error:代表的系统级别错误(属于严重问题),也就是说系统一旦出现问题,sun公司会把这些问题封装成Error对象给出来,也就是说,Error是给sun公司自己用的,不是给我们程序员用的,因此开发人员不特别在意它。
Exception:意为异常,它代表的才是我们程序可能出现的问题,所以,我们程序员通常会用Exception以及它的孩子来封装程序出现的问题。
由分为两种:
- 运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如:数组索引l越界异常)
- 编译时异常:编译阶段就会出现错误提醒的。(如:日期解析异常)
例如:
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test1 {
public static void main(String[] args){
//运行时异常
// Integer.valueOf("abc");
//
// int[] arr = {11,22,33};
// System.out.println(arr[5]);
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)
- 直接捕获程序出现的异常。
try{
//监视可能出现异常的代码!
}catch(异常类型1 变量){
//处理异常
}catch(异常类型2 变量){
//处理异常
}...
抛出异常(throws)
- 在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理。
方法 throws 异常1,异常2,异常3...{
...
}
第一种方式:try...catch
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test1 {
public static void main(String[] args){
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();
}
}
}
第二种方式:抛给上层程序
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test1 {
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);
}
}
抛给上层程序,也就是JVM虚拟机;虚拟机实际上也会进行进行try catch.
自定义异常
- Java无法为这个世界上全部的问题都提供异常类来代表,如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。
自定义异常的种类
自定义运行时异常
- 定义一个异常类继承RuntimeException
- 重写构造器
- 通过throw new 异常类(xxx) 来创建异常对象并抛出
编译阶段不报错,提醒不强烈,运行时才可能出现!!
自定义编译时异常
- 定义一个异常类继承Exception
- 重写构造器
- 通过throw new 异常类(xxx) 来创建异常对象并抛出
编译阶段就报错,提醒更加强烈!
实例演示
需求一:保存合法年龄。
自定义运行时异常来处理:
1.首先自定义异常类
public class AgeIllegalRuntimeException extends RuntimeException {
//必须让这个类继承自 RuntimeException
public AgeIllegalRuntimeException() {
}
public AgeIllegalRuntimeException(String message) {
super(message);
}
//这样就算定义完成了
}
2.回到主程序,捕获错误
package user.Exception;
public class Test2 {
public static void main(String[] args) {
//需求:保存一个合法的年龄
try {
saveAge(222);
} catch (Exception e) {
e.printStackTrace();
System.out.println("底层出现了bug");
}
}
public static void saveAge(int age){
if(age > 0 && age < 150){
System.out.println("年龄保存成功: " + age);
}else{
//用一个异常对象封装这个问题
//然后再throw 抛出去这个异常对象
throw new AgeIllegalRuntimeException("/age is illegal,your age is " + age);
//写上异常提示
}
}
}
运行结果:
自定义编译时异常来处理:
异常类定义这里,和上面的方法是差不多的:(注意继承自Exception)
package user.Exception;
public class AgeIllegalRuntimeException extends Exception {
//必须让这个类继承自 Exception,才能成为一个编译时时异常类
public AgeIllegalRuntimeException() {
}
public AgeIllegalRuntimeException(String message) {
super(message);
}
//这样就算定义完成了
}
主程序:
package user.Exception;
public class Test2 {
public static void main(String[] args) {
//需求:保存一个合法的年龄
try {
saveAge2(222);
System.out.println("saveAge2底层执行时成功的!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("saveAge2底层出现了bug");
}
}
public static void saveAge2(int age) throws AgeIllegalRuntimeException {
if(age > 0 && age < 150){
System.out.println("年龄成功保存: " + age);
}else{
//用一个异常对象封装这个问题
// throw抛出去这个异常对象
// 再用throws,用在方法上,抛出方法内部的异常
throw new AgeIllegalRuntimeException("/age is illegal,your age is " + age);
}
}
}
运行结果:
异常有什么作用?
- 异常是用来查寻系统Bug的关键参考信息!
- 异常可以作为方法内部的一种特殊返回值,以便通知上层调用者底层的执行情况!
END
学习自:黑马程序员——JavaSE课程