异常
什么是异常
有异于常态,和正常情况不一样,有错误出现,阻止当前方法或作用域,称之为异常。java中所有的异常都继承与Throwable类。
Throwable类中有两个常用子类:
error类:虚拟机错误,线程死锁等。
Exception类:编码,环境,用户操作输入出现问题。
Exception
又分为RuntimeException(运行时异常/非检查异常)和检查异常
RuntimeException:会自动抛出捕获等
NullPointerException(空指针异常)
ArrayIndexOutOfBoundsException(数组下标越界异常)
ClassCastException(类型转换异常)
ArithmeticExceptior(算术异常)
检查异常
IOException(文件异常)
SQLException(SQL异常)
处理异常
try-catch当抛出异常时,抛出异常的方法会终止执行,程序的控制权将会被移交给catch快中的异常处理程序。
try{
//一些会抛出异常的方法
}catch(Exception e){
//处理该异常的代码块
}
多个catch语句块:先子类后父类,当程序抛出异常的时候,异常处理程序会就近寻找,而子类继承与父类,针对于父类的异常处理对于子类也同样适用。
try{
//一些会抛出异常的方法
}catch(InputMismatchException e){
//处理该异常的代码块
}catch(ArithmeticException e){
//处理该异常的代码块
}catch(Exception e){
//处理该异常的代码块
}
try-catch-finally:
package com.company.test0702;
public class test01 {
/**
* divide(除数)
* result(结果)
* try-catch捕获while循环
* 每次循环,divide减一,result=result+100/divider
* 如果;捕获异常,打印输出“抛出异常了!!”,返回-1
* 否则:返回result
*/
public int test1(){
int divider=10;
int result=100;
try{
while(divider>-1){
divider--;
result=result+100/divider;
}
return result;
}catch (Exception e){
e.printStackTrace();
System.out.println("循环抛出异常了");
return -1;
}
}
/**
* divide(除数)
* result(结果)
* try-catch捕获while循环
* 每次循环,divide减一,result=result+100/divider
* 如果;捕获异常,打印输出“抛出异常了!!”,返回result=999;
* 否则:返回result
* finally:打印输出“这是finally” 同时打印result
*
*/
public int test02(){
int divider=10;
int result=100;
try{
while(divider>-1){
divider--;
result=result+100/divider;
}
return result;
}catch (Exception e){
e.printStackTrace();
System.out.println("循环抛出异常了");
return result=999;
}finally {
System.out.println("这是finally");
System.out.println("result="+result);
}
}
public static void main(String[] args) {
test01 tt=new test01();
int result=tt.test1();
System.out.println(result);
int result2=tt.test02();
System.out.println(result2);
}
}
java中的异常抛出
throw–将产生的异常抛出(动作)
throws–声明将要抛出何种类型的异常(声明)
public void 方法名(参数列表)throws 异常列表{
//调用会抛出异常的方法或者:throw new Exception();
}
自定义异常与异常链
class 自定义异常类 extends 异常类型{
}
package com.company.test0704;
public class test01 extends Exception{
public test01(){
}
public test01(String message){
super(message);
}
}
package com.company.test0704;
public class ChainTest {
/*
*test1()抛出自定义的异常
* test2()捕获自定义异常,并包装成运行时异常,继续抛出
* main方法中,调用test2()方法抛出的异常
*/
public void test1() throws test01{
throw new test01("自定义异常");
}
public void test2(){
try{
test1();
}catch (Exception e){
//RuntimeException newEXc=new RuntimeException("自定义异常被捕获成为运行时异常");
RuntimeException newEXc=new RuntimeException(e);
//newEXc.initCause(e);
throw newEXc;
}
}
public static void main(String[] args) {
ChainTest ct=new ChainTest();
try {
ct.test2();
}catch (Exception e){
e.printStackTrace();
}
}
}
实际应用中的经验和总结
1.处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理。
2.在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常。
3.对于不确定的代码,也可以加上try-catch,处理潜在的异常。
4.尽量去处理异常,切忌知识简单的调用printStackTrace()去打印输出。
5.具体如何处理异常,要给根据不同的业务需求和异常类型去决定。
6.尽量去添加finally语句去释放占用的资源。