首页 > 代码库 > java之异常
java之异常
1.异常概述
异常就是java程序在运行过程中出现的错误。
2.异常的由来
问题也是现实生活中一个具体事物,也可以通过java类的形式进行描述,并封装成对象。其实java对不正常的情况进行描述后的对象体现。
3.异常例子
坐标越界异常,空指针异常。
4.异常图解
异常分为三类:
Error:用Error进行描述,这个问题发生后,一般不编写针对代码进行处理,而是要对程序进行修正,通常都是由虚拟机内部抛出的问题。
RuntimeException:运行时异常,这种异常不用处理,编译会通过,不过这样的程序会有安全隐患,遇到这种异常是需要修改代码的。
非RuntimeException:除了RuntimeException及其子类,Exception中的所有子类都是,这种异常必须处理,不然编译通不过。
5.java的默认处理异常机制
package cn; public class ExceptionDemo { public static void main(String[] args) { int a = 10; int b = 0; System.out.println(a /b); System.out.println("over"); } }
Exception in thread "main" java.lang.ArithmeticException: / by zero
at cn.ExceptionDemo.main(ExceptionDemo.java:8)
java的默认处理方案:
把异常的名称,错误原因及异常出现的位置等信息输出在了控制台。
程序停止了执行。
上面异常处理的过程是:
java发现运算时违反了数学运算规则,java将这种常见的问题进行描述,并封装成了对象叫做ArithmeticException。
当除以0运算发生后,java虚拟机将该问题打包成一个异常对象。
并把这个对象抛给调用者main方法,new ArithmeticException("/ by zero")
main方法受到这个问题,有两种处理方式。
1.自己将该问题处理,然后继续运行。
2.自己没有针对的处理方式,只有交给调用main方法的java虚拟机来处理。
6.异常处理方案
6.1 处理格式一:try..catch...finally
try{
//检测异常
}catch(){
//用来捕获异常
}finally{
//用来结束资源的
}
这种异常的好玩的句子就是:世界上最真情的相依,是你在try我在catch,无论你发神马脾气,我都默默接收,静静处理。
package cn; public class ExceptionDemo { public static void main(String[] args) { int a = 10; int b = 0; try{ System.out.println(a /b); }catch(Exception e){ e.printStackTrace(); } System.out.println("over"); } }
6.2throws处理异常
有些时候,我们是可以进行处理的,但是又有些时候,我们根本没有权限去处理某个异常。或者说,我处理不了,我就不处理了。
为了解决出错问题,java针对这种情况,就提供了另一种解决方案:抛出。
格式:
throws 异常类名
这个格式必须跟在方法的括号后面。
package cn; import java.text.ParseException; import java.text.SimpleDateFormat; public class ExceptionDemo { 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 = "2016-11-11"; System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s)); } }
今天天气很好
为什么要有雾霾
java.text.ParseException: Unparseable date: "2016-11-11"
at java.text.DateFormat.parse(DateFormat.java:366)
at cn.ExceptionDemo.method(ExceptionDemo.java:21)
at cn.ExceptionDemo.main(ExceptionDemo.java:10)
7.编译时异常和运行时异常的区别
java中的异常被分为两大类:编译时异常和运行时异常。所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常。
编译时异常:java程序必须显示处理,否则程序就会发生错误,无法通过编译。
运行时异常:无需显示处理,也可以和编译时异常一样处理。
8.Throwable中的方法
getMessage(): 获取异常信息,返回字符串
toString(): 获取异常类名和异常信息,返回字符串
printStackTrace():获取异常类型和异常信息,以及异常出现在程序中的位置,返回值类型void
printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。
9.throws关键字
定义功能方法的时候,需要把出现的问题暴露出来让调用者去处理,那么就通过throws在方法上标识。
10.throw
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
package cn; /** * throw:如果出现了异常情况,我们可以将该异常抛出,这个时候抛出的应该是异常的对象 * */ public class ExceptionDemo2 { public static void main(String[] args) { method(0); } public static void method(int b){ int a = 10; if(b == 0){ throw new ArithmeticException("除数不能为0"); }else{ System.out.println(a / b); } } }
Exception in thread "main" java.lang.ArithmeticException: 除数不能为0
at cn.ExceptionDemo2.method(ExceptionDemo2.java:13)
at cn.ExceptionDemo2.main(ExceptionDemo2.java:8)
package cn; /** * throw:如果出现了异常情况,我们可以将该异常抛出,这个时候抛出的应该是异常的对象 * */ public class ExceptionDemo2 { public static void main(String[] args) { try { method(0); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void method(int b) throws Exception{ int a = 10; if(b == 0){ throw new Exception("除数不能为0"); }else{ System.out.println(a / b); } } }
java.lang.Exception: 除数不能为0
at cn.ExceptionDemo2.method(ExceptionDemo2.java:17)
at cn.ExceptionDemo2.main(ExceptionDemo2.java:9)
两段程序片段,结果差不多,为什么形式大不同?
第一个程序片段中,抛出了是RuntimeException的对象,是可以不处理的啊。
但是在第二个程序片段中,抛出了是Exception,这时java就认为了你必须处理,否则不让你编译通过哦。
而抛出的是RuntimeException,在方法上是可以不写throws的,因为是运行时异常,可以不处理。
但是一旦抛出的是非RuntimeException异常,那么恭喜你,要么直接处理,要么在方法的括号后写上throws 异常类名吧,因为此时java认为你必须处理。
11.throws和throw的区别?
throws
用在方法声明后面,跟的是异常类名。
可以跟多个异常类名,用逗号隔开。
表示抛出异常,由该方法的调用者处理。
throws表示出现异常的一种可能性,并不一定会发生这些异常。
throw
用在方法内,跟的是异常对象名。
只能抛出一个异常对象名。
表示抛出异常,由方法体内的语句进行处理。
throw则是抛出了异常,执行throw则一定抛出了某种异常。
12.我们该如何处理异常?
原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,就用throws.
区别:
后续程序需要继续运行就try。
后续程序不需要继续运行就throws。
13.finally
finally的特点:
被finally控制的语句体一定会执行。
但是如果在执行到finally之前JVM就退出了,那么finally就不起作用了,即此时被finally控制的语句体不会执行。
finally作用
用于释放资源
14.final,finally和finaalize的区别?
final是最终的意思,可以修饰类,成员变量和成员方法。
final修饰类,类不能被继承。
final修饰变量,变量是常量。
final修饰方法,方法不能被重写。
finally:是异常处理的一部分,用于释放资源。
一般来说,代码肯定会执行,但是,如果在执行到finally之前,JVM退出了,怎么还可能执行呢?
finalize:是Object类的一个方法,用于垃圾回收。
15.自定义异常
java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。而我们随意的一个类,是不能作为异常类来看的,要想你的类是一个异常类,就必须继承自Exception或RuntimeException。
package cn; @SuppressWarnings("serial") public class MyException extends Exception{ public MyException(){} public MyException(String message){ super(message); } }
16.异常的注意事项
16.1 子类重写父类方法时,子类的方法必须抛出相同的异常或者父类异常的子类。
class Fu{ public void method() throws Exception{ } } class Zi extends Fu{ public void method() throws Exception{ } }
class Fu{ public void method() throws Exception{ } } class Zi extends Fu{ public void method() throws ArithmeticException{ } }
为什么呢?因为子类重写父类的方法,是因为子类需要扩充父类的功能,既然要扩展父类的功能,那么子类抛出的异常要么和父类相同,要么就比父类具体。(父亲坏,儿子不能比父亲更坏吧,不然,会被人家骂,上梁不正下梁歪)
16.2 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者他的子集,子类不能抛出父类没有的异常。
16.3 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,却不能throws。
class Fu{ public void method() throws Exception{ } public void method2(){ } } class Zi extends Fu{ public void method() throws ArithmeticException{ } public void methods(){ String str = "2016-11-11"; try { Date d = new SimpleDateFormat("yyyy-MM-dd").parse(str); System.out.println(d); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
本文出自 “11831428” 博客,请务必保留此出处http://11841428.blog.51cto.com/11831428/1864643
java之异常