异常
1.异常的概述和分类
java中的异常有一个超类Throwable,然后其有俩个子类接口Error和Exception,其中Error是严重问题,这一个是程序中无法解决的,而另一个
Exception则是一般问题。
Exception又可以分为俩个:
(1).编译时期异常:不是RuntimeException的异常,这一个是必须处理的,因为你不处理,编译就无法开始。
(2).运行时期异常:RuntimeException的异常,这一个问题也不能够出来,这是我们程序中在编写的时候不够严谨。需要修正代码。
2.JVM默认是如何处理异常
如果说一个程序出现了问题,而我们没有做任何的处理,最终jvm就会给出默认处理:
(1).把异常的名称,原因以及出现的问题等信息输出到控制台。
(2).终止程序的继续执行。
3.java提供的俩种异常处理方式
(1).try...catch...finally[自己内部处理]
(2).throws[抛出异常,让别人去处理]
4.异常处理方式1:try...catch...finally
(1).概述
使用该异常处理方式可以再程序的内部自己把异常可能出现的问题查找出来,并抛出,然后继续执行之后的代码。
(2).使用格式
try{
//可能出现异常的代码
}catch(异常名 变量){
//针对问题的处理
}finally{
//释放资源
}
变形格式:我们在实际的开发中,可能只需要用到try...catch...
即:
try{
//可能出现异常的代码
}catch(异常名 变量){
//针对问题的处理
}
//使用注意事项:
(1).try{}里面的代码越少越好,为什么?
因为jvm在处理异常代码的时候,需要对其进行特殊的处理,这一个时候需要给它分配一些资源来管理这一个异常代码,那么
你放置的代码越多,需要的资源就会越多。
(2).catch里面必须有代码,哪怕是一个简单的输出语句,如果不给出,那么就是隐藏异常。
(3).一个try...catch...处理一个异常的基本案例
public static void main(String[] args) {
int a = 10;
int b =0;
//异常处理
try {
System.out.println(a / b);
} catch (Exception e) {
// TODO: handle exception
System.out.println("除数不能够为0");
}
//查看程序是否继续执行
System.out.println("程序已经继续执行");
}
//输出结果:
除数不能够为0
程序已经继续执行
(4).try...catch...处理多个异常
A:处理的格式
try{
//可能出现异常的代码
}catch(异常名1 变量1){
//针对问题的处理
}catch(异常名2 变量2){
//针对问题的处理
}catch(异常名3 变量3){
//针对问题的处理
}
......
//注意:
(1).一旦try里面的代码出现问题,那么这一个时候就会去找和这一个异常匹配的catch,如果这一个时候try里面还有其他代码,那么将不会执行。
进而继续执行后面的代码。
(2).对于异常的处理,能明确异常的类型就明确,如果说实在不行,就使用一个带的异常去包,如直接使用Exception去抛。
也就是说对于异常的抛出或者是处理,应该是从小范围到大范围这样处理。
B:代码体现
public static void main(String[] args) {
int a = 10;
int b =0;
int[] arr = {1,2,3};
//异常处理
try {
System.out.println(a / b);
System.out.println(arr[3]);
} catch (ArithmeticException e) {
// TODO: handle exception
System.out.println("除数不能够为0");
} catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("数组索引越界");
}
//查看程序是否继续执行
System.out.println("程序已经继续执行");
}
//输出结果:
除数不能够为0
程序已经继续执行
5.JDK7对异常处理的新特性
(1).格式
try{
//可能出现异常的代码
}catch(异常名1|异常名2|异常名3.... 变量){
//针对问题的处理
}
//注意事项:
A:处理方式是一致的,也就要求异常的提示要求要对于同一个类型的异常才可以有效
B:多个异常之间必须是平级关系,不可以使用Exception
(2).代码实现
public static void main(String[] args) {
int a = 10;
int b =0;
int[] arr = {1,2,3};
//异常处理
try {
System.out.println(a / b);
System.out.println(arr[3]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
System.out.println("数据操作异常");
}
//查看程序是否继续执行
System.out.println("程序已经继续执行");
}
6.编译时期异常与运行时期异常区别
(1).编译时期异常
java程序必须显示处理,否则程序就会发生错误,无法通过编译。
(2).运行时期异常
无需显示处理,出现问题是在运行时候发生,也可以和编译时期异常一样处理。
7. 异常中要了解的几个方法:
public String getMessage():异常的消息字符串
public String toString():返回异常的简单信息描述
此对象的类的 name(全路径名)
": "(冒号和一个空格)
调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。
8.异常处理方式2:throws
(1).什么时候适合使用Throws
定义功能方法的时候,需要把出现的问题暴露出来让调用者去处理。那么就可以使用throws在方法上标识。
(2).格式
throws 异常类名
注意:这一个格式必须跟在方法的后面。
(3).throws基本使用测试
public static void main(String[] args) {
System.out.println("程序开始了");
try {
method();
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("程序结束了");
}
//在方法上抛出异常
public static void method() throws ParseException{
String s = "2014-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(s);
System.out.println(d);
}
(4).throws和throw之间的区别
A:throw:用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常
使用举例:
public static void method() throws ParseException{
int a = 10;
int b = 0;
if(b == 0){
throw new ArithmeticException();
}else{
System.out.println(a / b);
}
}
B:throws:用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
9:如何判断并选择使用异常
(1).原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws
(2).区别:
后续程序需要继续运行就try
后续程序不需要继续运行就throws
(3)举例:
感冒了就自己吃点药就好了,try
吃了好几天药都没好结果得了H7N9,那就的得throws到医院
如果医院没有特效药就变成Error了
10.finally关键字以及其作用
(1).finally的特点
A:被finally控制的语句体一定会执行
B:特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))
(2).finally的作用
用于释放资源,在IO流操作和数据库操作中会见到
(3).final,finally和finalize的区别
final:
表示的是最终的意思,可以修饰类,成员方法,
修饰类,类不可以被继承
修饰变量,该变量是常量
修饰方法,方法不能够被重写
finally:
是异常处理的一部分,用于释放资源。
一般来说,代码肯定会被执行,特殊情况,在finally之前jvm退出了。
finalize:
是属于Object类的一个方法,用于垃圾回收。
(4).如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后
会,之前,准确的说是在return的中间的时候执行finally
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;//如果这样结果就是40了。
}
return a;
}
//输出结果:30
11.异常的注意事项
(1).子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
(2).如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
(3).如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws