一、异常基本知识点
1、异常:程序运行过程中出现的不正常的情况
2、异常的由来:程序运行过程中出现的不正常的情况,java把它的位置,原因,名字等进行了提取,得到了对应的异常对象,形成了各种异常类
3、异常的分类:
-
总类:throwable
-
两个子类:
Error:程序中出现的严重错误.不需要我们进行修改
Exception:出现的不严重的错误.我们可以去尝试进行改正 -
两种分类方式:
第一种:按照异常类是否是系统创建的
1)系统异常:系统已经生成好的异常
2)自定义异常:自己根据具体的情况自定义的异常
第二种:按照异常处理的时间点分类
1)编译异常(Checked Exception):在编译阶段就要进行处理—除RuntimeException之外的所有异常–跟异常相关的所有工作都需要我们手动操作
2)运行时异常(RuntimeException-unchecked Exception):在运行阶段进行处理—RuntimeException异常----所有工作系统都会自动完成
public class Demo2 {
public static void main(String[] args) {//4.抛给了这里,这里也没有处理的能力,继续向上抛,
//抛给JVM,JVM会调用异常对象的打印方法,将异常的原因,名字,位置等打印到控制台
Math math = new Math();
math.div(3, 0);//3.抛给了这里,这里也没有处理的能力,继续向上抛
}
}
class Math{
public int div(int a,int b){//2.抛给了这里,这里也没有处理的能力,继续向上抛
return a/b;//1.先创建除数为零的异常对象(new ArithmeticException()),这里没有处理异常的能力,
//将生成的异常对象向上抛(throw new ArithmeticException()),
// 抛给这行代码所在的方法
}
}
4、异常的特点:当程序出现异常的时候,会打印异常信息并终端程序.所以当同时出现两个异常的时候,只能执行第一个。
public class Demo3 {
public static void main(String[] args) {
int[] arr = new int[]{3,4,5};
//ArrayIndexOutOfBoundsException:数组下标越界异常
//System.out.println(arr[10]);
//NullPointerException:空指针异常
arr = null;
System.out.println(arr[1]);
}
}
二、真正处理异常的方法
1、真正处理异常的方法:检测异常,捕获异常,让当前的异常不影响下面代码的执行.
try{
可能发生异常的代码
}catch(Exception e){//捕获异常 e:代表捕获的异常
对发生异常的代码进行处理
}
//下面的代码可以继续执行
public class Demo4 {
public static void main(String[] args) {
Math1 math = new Math1();
try{
math.div(3, 0);//3.抛给了这里,这里也没有处理的能力,继续向上抛
//只要try内部的代码发生了异常,catch会立刻捕获,这里的代码不会执行
//只有try里面的代码没有发生异常,这里的代码才会执行
System.out.println("可以执行吗");
}catch (Exception e) {//e = new ArithmeticException() 多态
//e.printStackTrace();//异常的原因,位置,名字
//System.out.println(e.toString());//异常的原因,名字
System.out.println(e.getMessage());//异常的原因
//对异常的处理
}
System.out.println("go on");
}
}
class Math1{
public int div(int a,int b){//2.抛给了这里,这里也没有处理的能力,继续向上抛
return a/b;//1.先创建除数为零的异常对象(new ArithmeticException()),这里没有处理异常的能力,
//将生成的异常对象向上抛(throw new ArithmeticException()),
// 抛给这行代码所在的方法
}
}
2、多捕获异常
try{
可能发生异常的代码
}catch(异常一 e){//捕获异常 e:代表捕获的异常
对发生异常的代码进行处理
}catch(异常二 e){
对发生异常的代码进行处理
}catch(Exception e){
对发生异常的代码进行处理
}
public class Demo5 {
public static void main(String[] args) {
Math2 math2 = new Math2();
try{
math2.div(3, 0);
}catch (ArithmeticException e) {//捕获除数为零异常
System.out.println("除数为零异常");
}catch (ArrayIndexOutOfBoundsException e) {//捕获下标越界异常
System.out.println("下标越界异常");
}catch (Exception e){//注意:要将捕获Exception的catch放在所有catch的最下面
System.out.println("其他异常");
}
System.out.println("go on");
}
}
class Math2{
public int div(int a,int b){
int[] arr = {2,3,5};
//System.out.println(arr[10]);
return a/b;
}
}
3、finally中放必须执行的代码
1)
try{
可能发生异常的代码
}catch(Exception e){
对发生异常的代码进行处理
}finally{
必须执行的代码:用于资源的释放 比如:多线程中的Lock锁,数据库中的关闭数据库的操作,流中的关闭流的操作
}
2)
try{
获取资源
}finally{
必须执行的代码:用于资源的释放 比如:多线程中的Lock锁,数据库中的关闭数据库的操作,流中的关闭流的操作
}
注:如果catch中有return;语句,也要先执行finally中的代码,再结束此方法;如果catch中放的是System.exit(0);语句,就直接结束程序,不再执行finally中的代码。(使用 Demo6 进行验证)
public class Demo6 {
public static void main(String[] args) {
Math3 math2 = new Math3();
try{
math2.div(3, 0);
}catch (Exception e){//注意:要将捕获Exception的catch放在所有catch的最下面
System.out.println("其他异常");
//return;//让当前的方法结束,finally内部的代码可以继续执行
System.exit(0);//让当前的程序结束,finally内部的代码无法执行
}finally {
System.out.println("finally");
}
System.out.println("go on");
}
}
class Math3{
public int div(int a,int b){
return a/b;
}
}
三、自定义异常
1、自定义异常:自己定义的异常类,通常我们会去创建Exception的子类.
2、为什么要自定义异常类?
为了解决系统异常无法解决的问题,例如:订单异常,用户信息异常等
3、对异常的处理方式:
1)继续声明(一层一层往上抛)
声明后,调用者去处理,调用者处理不了,继续声明,最后交给JVM
2)通过try{ }catch( ){ }处理
这里可以真正实现异常的处理
4、自定义异常实例:除数为负数异常
让谁去处理异常更合适?
答:谁调用有异常的方法,谁负责处理异常.
5、
1)创建除数为负数的异常类:
class FuShuException extends Exception{
public FuShuException() {
super();
}
public FuShuException(String message) {
//注意:下面的代码必须写
super(message);
}
}
2)定义Math4类,其中的div( )方法手动抛出异常:
public class Math4 {
//通过throws实现声明异常--告诉别人我这个方法有可能发生异常
int div(int a,int b)throws FuShuException
{
//除数为负数异常
//异常的创建,异常的抛出
if (b<0) {
throw new FuShuException("除数为负数了");
}
return a/b;
}
boolean isFushu(int b){
if (b<0) {
return true;
}else {
return false;
}
}
}
3)使用自定义异常:
public class Demo7 {
public static void main(String[] args) //throws FuShuException
{
Math4 math4 = new Math4();
//使用异常
// try{
// math4.div(3, -2);
// }catch (FuShuException e) {
// e.printStackTrace();
// }
//使用普通的判断
boolean is = math4.isFushu(-2);
if (is == true) {
//这里是除数为负数成立的地方
}
}
}
6、解释FuShuException构造方法中的参数如何在打印方法中显示
(使用子类带参构造方法创建对象,在构造方法中使用super( message );方法将参数传递给父类构造方法。)
public class Demo8 {
public static void main(String[] args) {
Teacher teacher = new Teacher("除数为负数了");
teacher.printStackTrace();
}
}
class Person{//相当于Exception
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
}
public Person(String message) {
super();
this.message = message;
}
public void printStackTrace() {
System.out.println(this.getMessage());
}
}
//相当于FuShuException
class Teacher extends Person{
public Teacher() {
}
public Teacher(String message) {
super(message);
}
}
四、练习异常
package day13;
/*
* 使用自定义的异常类
* 老师用电脑上课
* 老师发生上课异常
* 上课时电脑发生蓝屏或者冒烟异常
*/
public class Demo9 {
public static void main(String[] args) {
Teacher1 teacher = new Teacher1();
try {
teacher.teach();
} catch (LaoshiException e) {
e.printStackTrace();
}
}
}
class Teacher1{
void teach() throws LaoshiException {
Computer computer = new Computer();
try {
computer.used();
} catch (LanpinException e) {
e.printStackTrace();
System.out.println("重启电脑,正常上课");
} catch (MaoyanException e) {
e.printStackTrace();
throw new LaoshiException("电脑坏了,停止上课");
}
}
}
class Computer{
void used() throws LanpinException, MaoyanException {
if(java.lang.Math.random()*10<4) {
throw new MaoyanException("电脑冒烟");
}else if(java.lang.Math.random()*10<8) {
throw new LanpinException("电脑蓝屏");
}else
System.out.println("正常上课");
}
}
class MaoyanException extends Exception{
public MaoyanException() {
super();
}
public MaoyanException(String message) {
super(message);
}
}
class LanpinException extends Exception{
public LanpinException() {
super();
}
public LanpinException(String message) {
super(message);
}
}
class LaoshiException extends Exception{
public LaoshiException() {
super();
}
public LaoshiException(String message) {
super(message);
}
}