目录
一、常的概念以及体系结构
1 .1什么是异常?
举个例子:比如人感冒生病了。对应的程序中,指程序运行时,出现了一些非语法错误的问题,比如:文件打不开、某数据格式不对应、网络不通顺等等。
1.2异常的概念
在java中,将执行过程中发生的不正常哪个行为称为异常
1.3 异常机制有什么作用呢?
比如:当张三感冒了去看医生,医生也对诊断了感冒,并开了药,但是张三依旧要继续正常生活,并不会因为感冒而不呼吸、不生活了。那么程序不像人一样,如果程序执行中出现了问题(异常)那么它会自己检测出来并很好的解决,以及程序还能继续运行结束吗?还有,像下载某个文件中,比如突然不能下载,那么你还是想程序告诉我出现了什么问题,而不是直接将程序结束。
1.4 java异常体系结构
(直接见图)
同时注意:
a : 这里的错误不是语法错误。在程序报错中就分为:语法错误+异常两种情况,即:是报错不一定是异常,异常一定是报错。像少打了分号,那么这就属于语法错误,但是像异常中的错误类:
b : Throwable是异常体系的顶层类,就是祖师爷级别,派生出两个子类,Error和Exception两个子类
c : Error:指的时JVM无法解决的严重问题,比如:JVM的内部错误,资源耗尽,典型代表:栈溢出等,一旦发生,那就是代码自身逻辑的问题,就像得了不可治疗的病。
d : Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行,比如:感冒、发烧。
e : 编译时异常:在程序编译期间发生的错误,也称:受检查异常(最明显的就是:不是语法错误,但是在编写代码时出现某类,某个方法处报红的情况),这种已换成那个必须程序员自己解决
f : 运行时异常:在程序运行期间出现的错误,也称非检查异常,比如:
public class day3 {
public static void main(String[] args) {
System.out.println(10/0);
}
}
在这里并没有任何问题,但是运行结果:
二、异常处理
2.1 5个重要的异常关键字
Throw、Throws、Try、Catch、Finally
2.2 异常处理
就目前为止,异常的处理方式有2种:一种是通过不负责的方式,一种是对异常做真正的处理。
2.3 Throws处理:
2.3.1 对于运行时异常:用Throws的方法
public class day3 {
public static void func(int a)throws ArithmeticException{
if(a==10){
throw new ArithmeticException();
}
System.out.println("这里没有问题");
}
public static void main(String[] args) throws ArithmeticException{
func(10);
System.out.println("哈哈");
}
}
运行结果:
但是你继续 不用抛异常来解决,会发现:
public class day3 {
public static void func(int a){
if(a==10){
throw new ArithmeticException();
}
System.out.println("这里没有问题");
}
public static void main(String[] args) {
func(10);
System.out.println("哈哈");
}
}
运行结果:
为什么有throws和没有的效果是一模一样的呢?那要throws有什么用呢?原来这是运行时异常,运行时异常就是运行时自己会解决的,JVM会自动处理。而Throws是用来解决编译时异常的。
2.3.2 对于编译时异常
程序中存在编译时异常,我们必须处理
改进代码:
public static void func(int a)throws IOException {
if(a==10){
throw new IOException();
}
System.out.println("这里没有问题");
}
public static void main(String[] args)throws IOException {
func(10);
System.out.println("哈哈");
}
运行结果:
注意的点:
a : throw必须写在方法体内
b : 抛出的异常必须是Ecxeption或者Exception的子类对象
c : 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
d : 如果抛出的运行时异常,用户可以不用处理
e : 异常一旦抛出或者出现,那么后面的代码讲不会再次执行,除非真正的用try-catch处理。
f : 抛的思想:某方法内出现异常,那么在方法上进行声明,然后再抛给调用该方法的方法,这样一级一级的向上抛,最终会抛给mian函数,同时main函数也必须进行声明,如果有多个异常,就在方法上用:throws 异常名1,异常名2,异常名3....(异常名之间用逗号隔开)。最终,Main函数就抛给了JVM处理。这种就有点一个企业里底层出事了,那么一层一层的向上司报告,最终董事长来处理。
2.4 Try-catch处理异常
throws并没有对异常实现处理,而是逃避的形式。那么Try-catch才是真正实现了对异常的处理
public static void func(int a) {
try {
if (a == 10) {
throw new ArithmeticException();
}
}catch(ArithmeticException e){
e.printStackTrace();
}
System.out.println("运行到这里了");
}
public static void main(String[] args) {
func(10);
System.out.println("哈哈");
}
}
注意看这里:
因为这里,try对有异常嫌疑的代码进行了捕捉,然后catch将异常打印出来,实现了解决,就是告诉给了JVM,然后JVM知道了就直接让程序继续,然后解决了,后面的代码继续正常执行。所以程序以返回值0结束了,而返回值1结束是不正常的。
注意:
a : try内抛出异常位置后的代码不会再次被执行
b : 如果抛出的异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续向外抛,直到JVM收到后中程序——异常是按照类型来捕获的
c : try可能会抛出多个不同的异常对象,则必须用多个catch来捕获——即多种异常,多次捕获,如果多个异常的处理方式是完全相同,那么可以直接写成:
d : 如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则语法错误。可以这样理解:如果子异常在前,而父类一定可以捕获所有的异常,那么子类已经在前被捕获了,这样子类再被写在父类的后面是不起作用的。
2.5.1 finally关键字用于关闭资源
2.5.2 finally程序中的return
观察下面代码:
结果:
总之finally里一定会执行的,在try里写catch没用,尽量不要在finally里写return ;
在finally不写return 那么将会显示没有返回值
像以下情况结果是10,因为没有产生异常,于是直接在return10处结束
再像以下情况:
结果就是9,因为产生异常,捕捉异常,也解决了异常,再运行到了return9
对于此处的理解就是:首先看try里面有没有异常:
没有异常:
直接先执行return了,然后看有没有finally,有finally则覆盖try里的return,则返回finally里的return,没有finally则直接在try里的return结束,即使后面有return都不会再被执行
有异常:
有finally那么直接执行finally里的,没有finally则直接执行后面的return 。
三、自定义异常
Java中虽然已经内置了丰富的异常类,但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我们实际情况的异常结构。
自定义异常:
需要继承:Exception或者RunTimeException
注意事项:
a : 自定义异常通常会继承自Exception和RuntimeException
b : 继承自Exception的异常默认是受查检查
c : 继承自RunTimeException的异常默认非受查异常
public class UserNameErrorExecption extends Exception{
public UserNameErrorExecption(){
super();
}
}
public class LogIn{
private String userName="admin";
private String password="123456";
public static void loginInfo(String userName,String password)throws UserNameErrorExecption{
if(!userName.equals((userName))){
System.out.println("用户名错误");
return;
}
if(!password.equals(password)){
System.out.println("密码错误");
throw new UserNameErrorExecption();
}
System.out.println("登录成功");
}
public static void main(String args)throws UserNameErrorExecption{
loginInfo("admin","123456");
}
}
总之:初步要知道异常是什么、有什么作用、异常的处理机制、如何自定义一个异常。散会!下篇见。