在后期学习过程中发现对于异常这部分掌握地并不是特别扎实,所以利用一个时间来好好复习下其中的具体知识。
异常的来源
天有不测风云,在我们编程过程中,总会出现或多或少的错误,而有些错误是我们可以通过修改代码解决的,这些错误称为异常,但是有些错误是不能通过修改代码解决的,必须通过其他方式解决,这些错误称为ERROR。
异常的继承
所有的异常继承一个父类Throwable,这个父类又继承Object,在Throwable类下又有两个子类Error和Exception,一般情况下,Error的错误是不能通过修改代码直接解决的,运行时出现这种错误,程序就直接终止;另外Exception类下分为运行时异常和非运行时异常,运行时异常不是强制被捕获的,属于在java虚拟机正常运行时可能出现的异常,在不被捕获的情况下可以通过编译,但是会在执行时可能会输出异常信息此运行时异常都继承RunTimeException;而非运行时异常,必须实现捕获并处理,又叫受检查异常,JDK调用者这必须处理,所有非运行时异常都继承Exception。
异常的分类
在谈及整个异常的框架后,那么异常又分为哪些呢?
运行时异常,一般有ParseException、NullPointerException等,而非运行时异常,又有SQLException、IOException等,具体见如下图:
异常的处理方式和用法
- try-catch
-
- try-catch属于常见的强制性处理异常的方式,其运行原理如下:
- try-catch属于常见的强制性处理异常的方式,其运行原理如下:
-
- 例如:
public static void main(String[] args){
NoRunTimeExceptionDemo nrte = new NoRunTimeExceptionDemo();
boolean flag = false;
System.out.println("---------第三个方法:throws的演示实例---------");
try{
flag = nrte.exceptionMethod2();//输出一、异常信息、false
}catch(ParseException e){
e.printStackTrace();
}
System.out.println(flag);
}
/**
* 1.try-catch演示实例
*/
public boolean exceptionMethod(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try{
System.out.println("输出一");
Date date = sdf.parse("10-09");
System.out.println("输出二");
}catch(ParseException e){
System.out.println("输出三");
e.printStackTrace();//以五十步笑百步
}catch(Exception e){ //这种写法欠妥,希望今后不要出现
System.out.println("输出四");
e.printStackTrace();
}
System.out.println("输出五");
return true;
}
- try-catch-finally
-
- try-catch-finally属于常见的强制性处理异常的方式,其运行原理如下:
- try-catch-finally属于常见的强制性处理异常的方式,其运行原理如下:
-
- try-catch-finally处理异常方式中,finally中代码是一定会执行的,只有在JVM退出的情况下,才会不执行,因此需要注意在finally中不能使用return。
- 例如:
public static void main(String[] args){
NoRunTimeExceptionDemo nrte = new NoRunTimeExceptionDemo();
boolean flag = false;
System.out.println("---------第二个方法:try-catch-finally的演示实例---------");
flag = nrte.exceptionMethod1();//输出一、输出三、异常信息、finally中的代码一定会执行的!、true
System.out.println(flag);
}
/**
* 2.try-catch-finally演示示例
*/
public boolean exceptionMethod1(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try{
System.out.println("输出一");
//版本一 进入catch
Date date = sdf.parse("10-09");
//版本二 不进入catch
//Date date = sdf.parse("1970-10-09");
System.out.println("输出二");
}catch(ParseException e){
System.out.println("输出三");
e.printStackTrace();
return true;
}finally{
System.out.println("finally中的代码一定会执行的!");
}
System.out.println("输出四");
return false;
}
其特点是在return运行之前,执行finally中代码块。
* throws
* * 属于异常处理的另一种方式,在实在处理不了的情况下,可以选择将异常抛出给上一层,让调用者来处理。其特点是,一旦抛出异常的代码,那么这句代码以后的代码都不执行。
* 例如:
public static void main(String[] args){
NoRunTimeExceptionDemo nrte = new NoRunTimeExceptionDemo();
boolean flag = false;
System.out.println("---------第三个方法:throws的演示实例---------");
try{
flag = nrte.exceptionMethod2();//输出一、异常信息、false
}catch(ParseException e){
e.printStackTrace();
}
System.out.println(flag);
}
/**
* 3.throws的演示实例
* @throws ParseException
*/
public boolean exceptionMethod2() throws ParseException{ //此处抛出去的异常必须在调用者处捕获!!!!
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("输出一");
Date date = sdf.parse("11-09");//此处抛出异常,后续代码将不执行
System.out.println("输出二");
return false;
}
-
- throw和throws的区别
-
-
- Throws一般用在方法声明后面,跟的是异常类名,而Throw用字方法体内,跟的是异常对象名;
-
-
-
- Throws可以跟多个异常名,用逗号隔开,而Throw只能抛出一个异常对象名;
-
-
-
- Throws表示抛出异常,由该方法的调用者来处理,而Throw表示抛出异常,由方法体内的语句处理;
-
-
-
- Throws表示出现异常的一种可能性,并不一定会发火说呢过这些异常,而Throw则是抛出异常,执行Throw则是一定抛出了某种异常。
-
自定义异常
- 在有些情况下,所提供的异常是不能完全解决目前的问题,那么需要自定义异常,其步骤也很简单,具体如下:
-
- 第一步:创建一个普通的类,如MyException;
-
- 第二步:将该类继承Exception或RunTimeException;
-
- 第三步:写构造函数,一个是无参构造函数,另一个带有String message 的有参构造按函数,然后继承父类的,有需要也可以重写父类中需要的方法。
-
- 第四步,使用自定义的异常,方式和普通异常相似。
- 例如:
/**
* 自定义异常
*/
public class MyException extends RuntimeException{
public MyException(){}
public MyException(String message){
super(message);
}
}