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一定要放在下面。
什么是异常?
异常就是程序运行时出现的不正常情况。
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一定要放在下面。