异常概述:
异常:就是java程序在运行过程中出现的错误或者出现了不正常的情况
异常的由来:问题也是现实生活中以恶具体事务,也可以通过java的类
的形式进行描述,并封装成对象,其实就是java对不正常
情况进行描述后的对象体现
我们见过的异常:比如数组索引(下角标)越界异常,控指针异常
Throwable类是java语言中所有错误或异常的超类,两个子类 Error , Exception
严重问题:Error 我们不处理,这种问题一般都很严重,比如说内存溢出
问题:Excetption
运行期问题:RuntimeException,在编译期间这种问题我们不处理,因为是我们程序员本身的问题导致,而且这个问题出现肯定是我的代码不够严谨,需要修正代码。
编译期问题:不是RuntimeException的异常 ,必须进行处理的,因为你不处理,编译就不能通过
JVM默认的异常处理方式
如果程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理
把异常的名称,原因及出现的问题等信息输出在控制台
同时会结束程序,代码就不会往下执行了
基于这一弊端,需要我们自己来处理异常
处理方案有两种:try...catch...finally
throws 抛出
格式:
try{
可能出现问题的代码
}catch(异常名 变量){
针对问题的处理;
}finally{
释放资源;
}
变形格式
try{
可能出现问题的代码
}catch(异常名 变量){
针对问题的处理;
}
注意:try里面的代码越少越好,catch里面必须有内容,哪怕是给出一个简单的提示
多个异常同时出现catch就对应写多个,但只写一个try,一旦try里面出了问题,就会在这里把问题给跑出去
然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try...catch ,继续执行后面的语句
能明确的尽量明确,不要用大的来处理
平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面
JDK7出现了一个新的异常处理方案
try{
}catch(异常名|异常名1|异常名2 变量名){}这样的情况是在提示一样的时候
这种方式虽然简洁,但是也不够:
1:处理方式是一致的,在实际开发中,好多时候可能就是针对同类性的问题,给出同一个处理
2:多个异常间必须是平级关系
编译期异常和运行期异常的区别:
编译期异常:java程序必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常:无需显示处理,也可以和编译时异常一样处理
在try里面发现问题后,jvm会帮我们生成一个异常对象,然后把这个对象抛出,和catch里面的类进行匹配
如果该对象时某个类型的,就会执行该catch里面的处理信息
异常中要了解的几个方法:
getMessage(): 异常的消息的字符串
toString() :返回异常的简单信息描述 此对象的类名: getLocalizedMessage() 方法的结果(默认返回的是getMessage()的内容)
printStackTrace()获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void,把信息输出在控制台,异常后面的语句也会执行,所以我们经常使用这个方法将异常内容保存在日志文件中
异常处理的第二个方案:throws
定义功能方法时,需要把出现的问题暴露出来让调用者去处理,那么就通过throws
在方法上标识
有些时候,我们时可以对异常进行处理的,但是又有时候,我们根本就没有权限去处理某个异常
或者说,我处理不了,就不处理了
为了解决出错问题 java针对这种情况就提供了另一种处理方案:抛出
格式:throws 异常类名
注意:这个格式必须跟在方法的括号后面
这样的目的是在方法声明上抛出,是为了告诉调用者,这里有问题,
尽量不要在main方法上不要抛出异常
编译期异常抛出将来调用者必须处理,
运行期异常抛出,将来调用者可以不用处理,、
throws后面可以跟多个异常类名
throw在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出
throw:如果出现了异常情况,我们可以把该异常抛出,这个时候抛出的应该时异常的对象
public class Exception{
public static void main(String[] args){
methos();
}
public static void method(){
int a = 10;
int b = 0;
if(b==0){
throw new ArithmeticException();
}else{
System.out.println(a/b);
}
}
}
throws 和 throw的区别:
throws 用在方法声明后,跟的是异常类名,
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throw 用在方法体内, 跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定跑出来某种异常
throws表示出现异常的一种可能性,并不一定会发生这些异常
到底该如何处理异常呢?
原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理用throws
区别:后续程序需要继续执行就try ,后续程序不需要继续执行就throws
举例:感冒了就自己吃点药就好了,try
吃了几天药都没好结果得了H7N9,那就得throws到医院,如果医院也无能为力就变成Error了
finally:被finally控制的语句体一定会执行
注意:如果在执行到finally之前jvm退出了,就不能执行了,比如System.exit(0)
作用:用于释放资源,在IO中和数据库中常用
final:最终的意思,可以修饰类,成员变量,成员方法
修饰类,类不能被继承
修饰变量,变量是常量
修饰方法,方法不能被重写
finally:是异常处理的一部分,用于释放资源
一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
finalize:是Object类的一个方法,用于垃圾回收
如果catch里面有return语句,请问finally里面的代码还会执行吗?
如果会请问是在return之前,还是return后
答:准确的说:会,它的执行是在执行两次return的中间
public class FinallyDemo{
public static void main(String[] args){
System.out.println(getInt());
}
public static int getInt(){
int a =10;
try{
System.out.println(a/ 0);
a=20;
}catch(ArithmeticException e){
a=30;
return a;
/
return a 在程序执行到这一步的时候,这里不是return a 而是return 30;这个返回
路径就形成了。但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
再次回到以前的返回路径,继续走return 30
/
}finally{
a=40;
}
return a;
}
}
try...catch...finally的格式变形
try...catch...finally
try...catch
try...catch...catch...
try...catch...catch...finally
try...finally:这种做法的目的是为了释放资源
如果我现在有个需求。 考试成绩必须在0-100之间
继承Exception 编译需要检查
继承RuntimeException 编译不需要检查
要想自定义的类作为异常类来看,就必须继承子Exception或者RuntimeException
public class MyException extends Exception{
public MyException(){}
public MyException(String message){
super(message);
}
}
public class Teacher{
public void check(int score)throws MyException{
if(score>100||score<0){
throw new MyException(“分数必须在0-100”);
}else{
System.out.println("分数没问题 ");
}
}
}
测试类:略
如果这里的MyException是继承自RuntimeException 就不需要在方法的括号后面写throws MyException
异常的注意事项:
子类覆盖父类方法时,子类的方法抛出相同的异常或父类异常的子类。
如果父类抛出了多个异常,子类重写父类时,只能抛出形同的异常或者时他的子集,子类不能抛出父类没有的异常
如果被重写的方法没有异常的抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
共同学习,写下你的评论
评论加载中...
作者其他优质文章