java异常

Java异常
什么是异常?
异常就是程序运行时出现的不正常情况。

class Demo
{
  //除法运算
  public int div(int a, int b){
  return a/b;
  }
}

Demo d = new Demo();
int x = d.div(4,0);
System.out.print(x);
System.out.println(“.over”);
当调用者往里传入除数0,就发生了编译通过,运行失败的情况。
出现了一个ArithmeticException:
Jvm发现运算时已经违反了数学运算规则,java将这种问题进行描述,
并封装成了对象:ArithmeticException。
当除0运算发生后,jvm会将该问题打包成一个异常对象。
New ArithmeticException(“/ by zero”);
Main函数收到这个问题时,有两种处理方式:
1.自己将问题处理掉,然后进行运行
2.自己没有针对性的处理方式,只有交给调用main的jvm来处理。
Jvm有一个默认的异常处理机制,就将该异常进行处理。并将该异常的名称,异常的信息。异常出现的位置打印在了控制台上。同时将程序停止运行。


其实异常就是程序中出现的问题,这个问题包括问题的名称,问题的信息,以及问题出现的位置。这个问题中内部中的有很多,按照面向对象将这个问题封装成了对象。

通过if判断形势,也可以对问题进行处理。
但是这样会导致,问题处理代码和正常的业务流程代码都定义在了一起,不便于阅读,
当把问题封装成对象后,当该问题产生后,可以让程序进行跳转有一个特定的区域对问题惊醒处理,这样,异常的出现可以让问题代码和业务逻辑代码分离,提高了程序阅读性。

Java对常见的一系列问题进行了描述,并进行对象的封装。

问题分为两大类:
1.可以处理的问题
  一般用Exception(异常)来进行描述,这个问题可以有针对性的处理

2.重大错误问题
  用Error进行描述,这个问题发生后,一般不编写针对性的代码进行处理,而是要针对程序进行修正,通常都有jvm抛出的问题。
  
这两个派系,他们的子类都有一个共同特征:
所有子类名成结尾都是以父类名作为后缀。
无论错误,异常,他们都有名称标示,同时也有问题的信息。问题出现的位置。
既然有这样的共性,可以向上抽取,
他们有了一个共同的父类Throwable,该父类定义了该体系中最共性的方法


String getMessage():获取异常信息
String toString():将异常对象变成字符串,其实覆盖了ObjecttoString方法
void printStackTrace():打印异常在内存中的详细信息。(异常名称,异常信息,异常位置)
没有进行try catch处理时,由jvm默认处理结果和printStackTrace()处理结果一样,
说明jvm默认处理方式,就是在调用异常的printStackTrace()方法,并让程序停止。
  
  
  
异常的处理:
1.抛出throws
2.使用java中指定的代码块进行自定义处理
try{
  需要检测异常的代码;
}
catch(异常类 变量){
  异常处理代码;
}
finally{
  一定会被执行的代码;
}

到底是try好还是throws好?
原则:如果该功能可以将问题处理,用try,如果处理不了,交由调用者处理,这时用throws。


如果使用到了一个声明了异常的功能时,
必须要对应的throws或者try的方式处理,否则编译失败。
但是有一种情况。
当功能上声明的异常是一个特殊的异常子类时,这时该功能被调用,可以不用任何处理方式,一样可以编译通过,这个特殊异常就是Exception中的一个子类RuntimeException。(运行时异常)

异常分两种:
1.编译时被检测的异常,包括除了Exception子类RuntimeException以外的所有异常。
  如果在函数上声明,如果调用时,没有处理方式,编译不通过。
  而且这种异常需要有针对性的处理方式,是可被处理的。
2.编译时不被检测的异常:包括RunntimeException以及子类。
  该异常也称为运行时异常,如果功能声明了此异常,
  调用者可以不用任何处理方式。通过该异常不需声明。
  如果发生,就是需要程序停止,对代码进行修正。
  
在自定义项目中,也会有很多问题发生,这些问题,有可能是项目特有问题,
是没有被java所描述的。
那么这时,就需要我们继续按照java的异常思想,将特有问题也封装成对象。

自定义异常:
将特有的问题进行描述,并封装成对象。

自定义异常的步骤:
  定义一个类对问题描述。要想成为异常,必须继承异常类才可以。这样才可以成为异常体系中的一员。
  其实最根本的原因:异常体系和其他对象的不同之处在于异常体系都具备可抛性。
  异常的类和对象都可以被两个关键字所操作:throw,throws
  
if(b<0)
{
  throw new FuShuException(); //手动将异常封装成对象,并手动通过throw关键字将//异常抛出,引起程序的跳转,因为该异常发生后,运算时无法继续的
}


当函数内容通过throw抛出了一个编译时检测异常,必须有处理方式,要么try,要么throws


调用了声明异常的函数,处理时,对方声明什么异常,我们就处理什么异常。

自定义异常例子:
class FuShuException extends RuntimeException{
  FuShuException(String str){ //调用了父类的构造方法,将异常说明传递进去
  super(str);
  }
}

自定义异常可以继承Exception,也可以继承RuntimeException。
如果该问题发生,不需要声明需要是修正代码,那么就需要继承RuntimeException


throws和throw的区别?
1.throws用在函数上,用于声明该功能容易出现问题,可以调用者进行处理。
throw用在函数内,用于抛出指定的具体异常对象。
2.throws后面跟的是异常类,可以跟多个,中间用逗号隔开。
throw后面跟的是异常对象。
只有异常体系的类和对象才可以被这两个关键字所操作。


异常的封装,将本层的特定异常进行本层的处理。通过处理完对外暴露将问题告诉调用者,给调用者提供一个可以处理的异常,这就是异常转换。


关键字finally:
无论怎么样都会执行到,除非退出jvm虚拟机

什么时候使用finally?
用于关闭资源的代码。

try catch finally在使用的时候
try可以和catch相结合使用,也可以对应多个catch

如果没有catch,try可以和finall结合使用。
如果功能中,出现了编译时需要被检测的异常,如果没有被catch,就必须要throws声明,否则编译失败。

只有catch是处理异常的代码块。

异常的处理细节:
1.当子类覆盖父类时,如果父类的方法抛出了异常;
  那么子类覆盖父类要么不抛异常,那么抛出该异常或的该异常的子类。
2.如果父类抛出了多个异常,子类覆盖父类时,只能抛出这些异常的子集。

子类只能抛父类的异常或异常的子类或子集,子类不可以抛出父类没有的异常。
注意:如果覆盖的方法没有异常抛出,那么子类的方法绝对不可以抛出异常。
如果子类方法内还有异常发生,那么子类只能try,不能throws。

面试细节:当try对应多个catch时,如果catch的类型有继承关系,那么父类型的catch一定要放在下面。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值