目录
一.异常概述
异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是:
异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
二.异常体系
- 异常的根类是java.lang.Throwable,其下有两个子类:java.lang.Error与java.lang.Exception,平常所说的异常指java.lang.Exception。
- 子类 : Error 所有错误的父类
- 所有的错误的类名都是以Error结尾
- 错误是程序中出现了严重问题,不修改源代码,不能执行
- 人: 严重的疾病,不换器官就完了
- 子类 : Exception 所有异常的父类
- 所有的异常的类名都是以Exception结尾
- 程序中出现了一般性问题,处理掉,可以继续执行
- Exception分类
- RuntimeException : 运行异常
- 非RuntimeException : 编译异常
- Throwable类的方法: 所有的子类都具备
- String getMessage() 返回异常信息,详细信息
- String toString() 返回异常信息,简短信息
- void printStackTrace() 异常信息,追踪到标准错误流 (日志)
三.异常产生过程分析
四.异常处理方式--捕获异常
- 语法格式:
try{
被检测的代码
可能出现异常的代码
}catch( 异常类的类名 变量名 ){
异常的处理方式
}
try: 关键字 是尝试的意思,一旦出现异常
catch : 关键字 抓住异常, 捕获,进行处理
异常的处理方式: 【有catch抓住异常,就叫做处理了】
处理方式任意: 变量,new 对象,调用方法,判断,循环
public static void main(String[] args) {
int[] arr={1,2,3};
try {
int i = getArray(arr);
System.out.println(i);
}catch (Exception ex){
System.out.println("异常被处理掉");
}
System.out.println("程序结束");
}
public static int getArray(int[] arr){
return arr[5];
}
-
Throwable类的异常信息方法
public static void main(String[] args) {
int[] arr = {1,2,3};
try {
int i = getArray(arr);
System.out.println(i);
}catch (Exception ex){
// System.out.println("异常被处理掉");
//调用Throwable类方法
String message = ex.getMessage();
System.out.println("message="+message);// 5
String str = ex.toString();
System.out.println("str="+str);// java.lang.ArrayIndexOutOfBoundsException:
ex.printStackTrace();//异常信息: 包含了异常的类型,异常的原因,还包括异常出现的位置(主力)
}
System.out.println("程序结束");
}
public static int getArray(int[] arr){
return arr[5];
}
-
多个catch并行
多个catch并行: (异常类的类名),先后顺序
异常类之间没有继承关系的时候,平级异常,没有顺序
如果异常类之间有继承关系的时候,父类异常写在下面
public static void main(String[] args) {
try {
show(0);
}catch (NullPointerException ex){
System.out.println("处理空指针");
}catch (ArrayIndexOutOfBoundsException ex){
System.out.println("处理数组越界");
}
}
/**
* 需求,定义方法
* 造异常, 创建数组越界异常,创建空指针异常
*/
public static void show(int a){
if(a == 0){
int[] arr = new int[0];
System.out.println(arr[1]);
}else {
int[] arr = null;
System.out.println(arr.length);
}
}
-
catch合并
多个catch合并为一个
一个catch(异常类|异常类|异常类 变量) 异常是平级,不能有继承
public static void main(String[] args) {
try {
show(1);
}catch (NullPointerException | ArrayIndexOutOfBoundsException ex){
System.out.println("异常处理");
}
}
/**
* 需求,定义方法
* 造异常, 创建数组越界异常,创建空指针异常
*/
public static void show(int a){
if(a == 0){
int[] arr = new int[0];
System.out.println(arr[1]);
}else {
int[] arr = null;
System.out.println(arr.length);
}
}
五.异常处理方式--抛出异常
/**
* throw: 在方法内部抛出异常对象
* 只能写在方法里面,throw new 异常对象()
* throws: 在方法定义上使用,告知调用者有异常
* throws只能写在方法定义后,throws 写异常类名
*/
public class Demo01 {
public static void main(String[] args) {
try {
int area = getArea(-5);
System.out.println("面积是:"+area);
} catch (Exception e) {
System.out.println("边长不存在");
}
}
//定义方法,计算正方形面积(整数)
/*
用户调用方法时,传递
用户传递0或者负数
使用异常技术,手动抛出异常
关键字 throw new的异常对象()
getArea()方法,告诉调用者,我有异常!!
*/
public static int getArea(int i)throws Exception{
if(i<=0){
throw new Exception();
}
return i*i;
}
}
六.编译异常和运行异常
- 编译异常:
- 非RuntimeException,或者非他的子类都是编译异常
- 特点: 调用了一个抛出编译异常的方法
- sdf.parse("");编译异常,调用者必须处理,否则编译失败
- 处理: try catch , throws
- 运行异常:
- RuntimeException或者是他的子类都是运行异常:
- 特点: 调用了一个抛出运行异常的方法,不能处理的
- 一旦发生运行异常,程序人员修改代码
- 常见的四大运行异常:越界异常,空指针,类型转换,无效参数异常 IllegalArgumentException
七.finally代码块
/**
* finally代码块,跟随try catch出现
* try{
* 检测代码,
* 可能出现异常的代码
* }catch(){
* 捕获异常,处理异常
* }finally{
* 这里的代码,一定要执行
* 无论是否有异常
* }
* 使用finally代码块: 基本上用来释放资源
*/
public class ExceptionDemo {
public static void main(String[] args) {
try{
int[] arr = {1,2,3};
System.out.println(arr[5]);
}catch (Exception ex){
ex.printStackTrace();
}finally {
System.out.println("这里必须执行");
}
}
}
尽量: 不要在异常处理中,使用return
注意: finally只有一种情况下不执行
finally代码之前,System.exit(0)
八.自定义异常
- 为什么需要自定义异常类:
我们说了Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是SUN没有定义好的,此时我们根据自己业务的异常情况来定义异常类。,例如年龄负数问题,考试成绩负数问题。
在上述代码中,发现这些异常都是JDK内部定义好的,但是实际开发中也会出现很多异常,这些异常很可能在JDK中没有定义过,例如年龄负数问题,考试成绩负数问题.那么能不能自己定义异常呢?
public class FuShuException extends Exception{
public FuShuException(String s){
//子类构造方法,调用父类构造方法
super(s);
}
}
/**
* 自定义异常:
* JDK中,提供大量的异常,但是不够
* 传递负数边长,JDK没有定义过边长不能为负数的异常
*/
public class ExceptionDemo {
public static void main(String[] args) {
/* int[] arr = {1};
System.out.println(arr[5]);*/
try {
int area = getArea(-5);
System.out.println(area);
}catch (FuShuException ex){
ex.printStackTrace();
}
}
/**
* 定义方法,传递边长,计算面积
*/
public static int getArea(int a)throws FuShuException{
if( a <= 0){
//手动抛出异常,抛出自定义的异常
throw new FuShuException("边长是负数");
}
return a*a;
}
}
九.子父类异常问题
public class Fu {
public void show() {
}
}
public class Zi extends Fu {
public void show() {
SimpleDateFormat sdf = new SimpleDateFormat();
try {
sdf.parse("");
} catch (ParseException e) {
e.printStackTrace();
}
}
}
/**
* 子类父类的异常问题
* 子类继承父类,重写父类的方法
*
* A:
* 父类的方法show,抛出了异常,
* 子类重写方法show,子类可以抛出异常,也可以不抛出异常
* 但是子类抛出的异常,不能大于父类抛出的异常
* 父亲很坏,孩子不能比父亲更坏
*
* B: 父类的方法show,不抛出异常
* 子类就不能抛
* 但是: 如果子类调用了一个抛出异常的方法
* 子类: 无可选择,只能try...catch
* 子类方法重写,保持和父类一致性
*/
public class ExceptionDemo {
public static void main(String[] args) {
Fu fu = new Zi();
fu.show();
}
}