程序在运行过程当中出现不正常状况。是对问题的描述,将问题进行对象的封装。java
问题也是现实生活中一个具体的事物,也能够经过Java的类的形式进行描述,并封装成对象。数据库
一种是严重的问题,一种是非严重的问题。数组
对于非严重的:Java经过Exception类进行描述。
对于Exception可使用针对性的处理方式进行处理。
不管Error仍是Exception都具备一些共性内容。
好比:不正常状况的信息,引起缘由。jvm
Throwable |--Error |--Exception |--RuntimeException
异常体系的特色:
异常体系中的全部类以及被创建的对象都具有可抛性。ide
try { 须要被检测的代码 } catch(异常类 变量) { 处理异常的代码(处理方式) } finally { 必定会执行的语句; }
String getMessage();
String toString();
void printStackTrace();函数
class Demo { int div(int x,int y) { return x/y; } } public class ExceptionDemo { public static void main(String[] args) { Demo d = new Demo(); try { int z = d.div(1,0); System.out.println(z); } catch (Exception e) { //Exception e = new ArithmeticExceptin(); System.out.println(e.getMessage()); // /by zero System.out.println(e.toString()); // 异常名称:异常信息 e.printStackTrace(); // 异常名称:异常信息,异常出现的位置 //(jvm默认的处理异常的机制就是在调用printStackTrace()方法) } System.out.println("over"); } }
运行结果this
/ by zero java.lang.ArithmeticException: / by zero java.lang.ArithmeticException: / by zero at Demo.div(ExceptionDemo.java:3) at ExceptionDemo.main(ExceptionDemo.java:10) over
class Demo { int div(int x,int y) throws Exception { return x/y; } } public class ExceptionDemo1 { public static void main(String[] args) throws Exception { Demo d = new Demo(); int y = d.div(1,0); System.out.println(y); System.out.println("over"); } }
class Demo { int div(int x,int y) throws Exception { return x/y; } } public class ExceptionDemo2 { public static void main(String[] args) { Demo d = new Demo(); int y = d.div(1,0); System.out.println(y); System.out.println("over"); } }
上述代码编译会提示:code
Error:(9, 22) java: 未报告的异常错误java.lang.Exception; 必须对其进行捕获或声明以便抛出
咱们对可能出现的异常加以处理:对象
class Demo { int div(int x,int y) throws Exception { return x/y; } } public class ExceptionDemo3 { public static void main(String[] args) { Demo d = new Demo(); try { int y = d.div(1,0); System.out.println(y); } catch (Exception e) { System.out.println(e.toString()); } System.out.println("over"); } }
运行结果:继承
java.lang.ArithmeticException: / by zero over
对可能出现异常的div方法进行处理以后,程序能够正常编译运行。
1.声明异常时,声明为更为具体的异常,这样能够处理得更具体。
2.方法声明有几个异常,对应就有几个catch块。(不要定义多余的catch块)
若是多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
class Demo { int div(int x,int y) throws ArithmeticException,ArrayIndexOutOfBoundsException { int[] arr = new int[x]; System.out.println(arr[3]); return x/y; } } public class ExceptionDemo4 { public static void main(String[] args) { Demo d = new Demo(); try { int y = d.div(2,0); } catch (ArithmeticException e) { System.out.println("被零除了"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("数组角标越界"); } } }
运行结果:
数组角标越界
上述代码中显然有两个一场出现,可是当方法中出现一个异常以后方法会中止运行,不会继续执行下去。
项目中会出现特有的问题,而这些问题并未被Java描述并封装对象。因此对这些特有的问题能够按照Java的对问题封装的思想,将特有的问题,进行自定义的异常封装。
需求:在本程序中,对于除数是负数,也视为是错误的。
当在函数内部出现了throw抛出异常对象,那么就必需要给对应的处理。
要么在内部使用try catch处理。
要么在函数上声明让调用者处理。
class FuShuException extends Exception { } class Demo { int div(int x,int y) throws FuShuException{ if(y<0) { throw new FuShuException();//经过throw关键字手动抛出一个自定义异常对象 } return x/y; } } public class ExceptionDemo5 { public static void main(String[] args) { Demo d = new Demo(); try { int y = d.div(1,-1); System.out.println(y); } catch (FuShuException e) { System.out.println(e.toString()); System.out.println("除数出现负数了"); } } }
运行结果
FuShuException 除数出现负数了
咱们能够发现以上的代码运行的结果中只有异常的名称,却没有异常的信息。由于咱们并未在自定义的异常中定义具体信息。
由于父类中已经把异常信息的操做完成了。因此子类只要在构造时,将异常信息传递给父类经过super语句,就能够经过getMessage方法获取自定义的异常信息。
class FuShuException extends Exception { private int value; FuShuException(){ super(); } FuShuException(String message,int value) { super(message); this.value = value; } public int getValue() { return value; } } class Demo { int div(int x,int y) throws FuShuException{ if(y<0) { throw new FuShuException("--被零除了--",y);//经过throw关键字手动抛出一个自定义异常对象 } return x/y; } } public class ExceptionDemo5 { public static void main(String[] args) { Demo d = new Demo(); try { int y = d.div(1,-1); System.out.println(y); } catch (FuShuException e) { System.out.println(e.toString()); System.out.println("除数出现了负数:"+e.getValue()); } } }
运行结果:
FuShuException: --被零除了-- 除数出现了负数:-1
自定义异常必须是是自定义类继承Exception
异常体系中的异常类和异常对象都具有可抛性,这个可抛性是Throwable这个体系中独有的特色。只有这个体系中的类和对象才能够被throw和throws操做。
异常分两种
RuntimeException是Exception中的一个特殊的子类。
若是在函数内容中抛出异常,函数上能够不用声明。
若是在函数上声明了异常,调用者能够不用进行处理。
之因此不用在函数上声明是由于不须要让调用者处理,当该异常发生,程序但愿中止,对代码进行修正,而不是去让调用者处理。
自定义异常时,若是该异常发生,没法再继续进行运算,就让自定义异常继承RuntimeException。
class FuShuException extends RuntimeException{ FuShuException(String message) { super(message); } } class Demo { int div(int x,int y) { //函数上为声明异常也能够正常编译 if (y < 0) { throw new FuShuException("--除数为负数--");//在函数内容中抛出异常 } else if(y == 0){ throw new ArithmeticException("--除数为零--");//在函数内容中抛出异常 } return x/y; } } public class ExceptionDemo6 { public static void main(String[] args) { Demo d = new Demo(); try { int y = d.div(1,-1); } catch (FuShuException e) { System.out.println(e.toString()); } catch (ArithmeticException e) { System.out.println(e.toString()); } } }
try { } catch () { } finally { }
finally中存放的是必定会被执行(不管是否有异常)的代码,即便catch中有return语句。
finally只有一种状况不会被执行,当代码执行到System.exit(0);
例如:若是须要对数据库进行操做,不管有没有成功链接上数据库,在最后操做完成的时候,都须要断开数据库的链接,以释放有限的资源。
try { } finally { }
将正常流程代码和问题处理代码相分离,加强代码可读性。
有圆形和长方形,均可以获取面积,对于面积,若是出现非法的数值,视为是获取面积出现问题。
出现的问题经过异常来表示。(使用异常能够,使问题处理代码和正常流程代码分开)
interface Shape { void getArea(); } class InvaidValueException extends RuntimeException {//若是一个传入一个图形的参数有错误,咱们没法对其进行有效的处理,只抛出异常便可,因此继承RuntimeException InvaidValueException(String message) { super(message); } } class Rec implements Shape { private double len,wid; Rec(double len,double wid) { if(len <= 0 || wid <= 0) throw new InvaidValueException("非法值"); this.len = len; this.wid = wid; } @Override public void getArea() { System.out.println(wid*len); } } class Circle implements Shape { private double r; public static final double PI = 3.14; Circle(double r) { if(r <= 0) throw new InvaidValueException("非法值"); this.r = r; } @Override public void getArea() { System.out.println(r*r*PI); } } public class ExceptionDemo7 { public static void main(String[] args) { Rec R = new Rec(1,2); R.getArea(); Circle C = new Circle(-1); C.getArea(); System.out.println("over"); } }
上述程序的运行结果为:
2.0 Exception in thread "main" InvaidValueException: 非法值 at Circle.<init>(ExceptionDemo7.java:28) at ExceptionDemo7.main(ExceptionDemo7.java:41)