本文共 7262 字,大约阅读时间需要 24 分钟。
异常是一种导致程序中断的指令流,如果不对异常进行正确的处理,则可能导致程序的中断指向,造成不必要的损失
Throwable是所有异常的父类
严重问题,这个问题发生后,一般不针对编写的代码进行处理,通常都是有Jvm抛出的问题。
运行时异常,该类及其子类都是,这种异常不处理,是可以编译通过的,但是运行时就会出错。
这类异常被称为编译时异常,这类异常必须要处理,不处理就运行不了。
这是异常常见的一种结构写法:
try{ 可能出现异常的代码:}catch(异常名称){ 处理方案:}finally{ 关闭资源}
public class ExceptionTest { public static void main(String[] args) { int a =10; int b =0;// System.out.println(a/b);//分母不能为0,运行时异常,算数异常ArithmeticException。// System.out.println("end"); try { System.out.println(a/b); }catch (RuntimeException e){ System.out.println("除数不能为0"); }finally { System.out.println("end"); } }}
里面代码越少越好,因为被try包裹着代码执行时要走异常处理机制,需要Jvm给该机制分配额外资源。
里面至少有一行代码
public class ExceptionTest { public static void main(String[] args) { int a =10; int b =0; int c[]={ 1,2,3}; // System.out.println(c[3]);//ArrayIndexOutOfBoundsException try { System.out.println(a / b); System.out.println(c[3]); }catch (ArrayIndexOutOfBoundsException e){ System.out.println("数组索引越界"); } catch (RuntimeException e){ System.out.println("除数不能为0"); } finally { System.out.println("end"); } }}
1.一个try多个catch
2.多个try对应多个catch,同时将多个异常抛出
3.一个try…catch,但是cath中异常写Exception,它可以匹配所有的子类异常
优点:省略了一些代码
缺点:try块中,如果前面的出现异常,则不会执行后面的代码。
1.同时存在多个异常时,当捕捉到第一个异常时,则直接跳转到finally,后续异常则不会再处理。
2.如果你不知道try中将会出现哪种异常,则可以使用父类的异常名称去捕获它(当然,能具体尽量具体)
3.多个异常中,存在等级关系,由小到大的捕获
public class ExceptionDemo3 { public static void main(String[] args) { int a =10; int b =0; int c[]={ 1,2,3}; try { System.out.println(a / b); System.out.println(c[3]); }catch (ArrayIndexOutOfBoundsException|ArithmeticException e){ //同级异常可以通过|写在一起 System.out.println("不好!有情况!"); } finally { System.out.println("end"); } }}
Throwable
类是 Java 语言中所有错误或异常的超类。
throw
语句抛出 ①返回此 throwable 的详细消息字符串。
public String getMessage()
②返回此 throwable 的简短描述。
public String toString()
③将此 throwable 及其追踪输出至标准错误流。
public void printStackTrace()
④将此 throwable 及其追踪输出到指定的输出流。
public void printStackTrace(PrintStream s)
/** * Throwable * */public class ExceptionDemo4 { public static void main(String[] args) { int a=0; int b=10; try{ System.out.println(b/a); }catch (Exception e){ System.out.println(e.getMessage());//返回此 throwable 的详细消息字符串。 System.out.println(e);//调用toString方法,打印异常类名和异常信息。 e.printStackTrace();//获取异常类名和异常信息,还有异常在程序中出现的问题,返回值void } }}
定义功能方式时,需要把出现的问题暴露出来,让调用者去处理。那么就需要通过throws在方法上标识。
权限修饰符 返回值类型 方法名()形参列表)throws 异常类型1,异常类型2…{}
1.throws必须跟在方法括号后面
2.一般情况下,throws别在main后面编译时的异常:以后谁调用该方法,一定要处理该异常。
运行时的异常:以后谁调用该方法,可以不一定处理该异常。public class throwsTest { public static void main(String[] args) { try { method(); } catch (Exception e) { e.printStackTrace(); } } public static void method()throws Exception { int a =0; int b =10; System.out.println(b/a); }}
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
public class throwDemo { public static void main(String[] args) { method(); } public static void method(){ int a=10; int b=0; if(b==0){ throw new ArithmeticException(); }else { System.out.println(a/b); } }// public static void method() throws Exception { // int a=10;// int b=0;//// if(b==0){ // throw new Exception();// }else { // System.out.println(a/b);// }// }}
throws
①用在方法声明后面,跟的是异常类名
②可以跟多个异常类名,用逗号隔开
③表示抛出异常,由该方法的调用者处理
④throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
①用在方法体内,跟的是异常对象名
②只能抛出一个异常对象名
③表示抛出异常,由方法体内的语句处理
④throw则抛出了异常,执行throw则一定抛出了某种异常
使用异常区别:
如果该功能可以将问题处理,就要try……catch处理
如果处理不了,就交给调用者处理,使用throws
区别:
如果程序还需要继续运行,就使用try……catch
如果程序不需要继续运行,就使用throws
被finally控制的语句体一定会执行
特殊情况下:在执行到finally之前jvm停止运行了,如System.exit(0)
public class finallyDemo { public static void main(String[] args) { int a=10; int b=0; try { System.out.println(a/b); }catch (Exception e){ System.out.println("分母不能为0"); //System.exit(0);有这句则不执行finally } finally { System.out.println("结束啦"); } }}
用于释放资源,在IO流操作和数据库操作中会见到。
final:最终的意思,可以修饰类,成员变量,成员方法
修饰类:类不能被继承 修饰变量:变量不能被修改 修饰方法:方法不能被重写 finally: 它是异常的一部分,用于释放资源。一般来说,无论异常是否发生,finally都执行。 finalize: Object的一个方法,用于垃圾回收会,并且在return之前执行。
准确来说,是在finally是在return运行中执行,先让 return 200,但是还没返回走,这时候发现还有finally语句,在执行finally语句,此时a=400,改变的是变量值,但是return 200 的这个路径已经形成,不能改变,因此返回200
public class finallyDemo2 { public static void main(String[] args) { System.out.println(method()); } public static int method(){ int a=100; try { System.out.println(a/0); }catch (Exception E){ a=200; return a; }finally { a=400; System.out.println(a); } return 0; }}
虽然java中有很多个异常类型,但是它只是我们常见的类型,并不能涵盖所有的异常。而我们在开发过程中,会遇到各种各样的异常,这时候我们就要使用自己定义的异常类的。
我们只需要写一个普通类,继承Exception,或者RuntimeException
①继承自Exception
②继承自RuntimeException
public class MyException extends Exception { public MyException(){ } public MyException(String s){ super(s);//一定要访问父类的有参构造,这样才能把异常信息打印到控制台 }}class Teacher{ public void check(int score) throws MyException { if(score>100 || score<0){ throw new MyException("成绩只能在0-100之间"); }else { System.out.println("你输入的成绩没问题"); } }}class Student{ public static void main(String[] args) throws MyException { System.out.println("请输入一个成绩:"); Scanner input =new Scanner(System.in); int score = input.nextInt(); Teacher t = new Teacher(); t.check(score); }}
①子类覆盖父类方法时,子类的方法必须抛出相同的异常或者父类异常的子类(父亲坏了,儿子不能比父亲更坏)
②如果父类抛出了多个异常,子类覆盖父类时,只能抛出相同的异常或者是它的子集,子集不能抛出父类没有的异常
③如果被覆盖的方法没有编译异常的抛出,那么子类的方法绝对不可以抛出编译异常,如果子类方法内有编译异常发生,那么子类只能try不能throws
public class MyException2 { public static void main(String[] args) { zi z = new zi(); z.show(); z.method(); }}class fu{ public void show() throws ArrayIndexOutOfBoundsException{ } public void method(){ }}class zi extends fu{ @Override public void show() throws ArrayIndexOutOfBoundsException{ super.show(); } @Override public void method() throws ArithmeticException{ int a =10; int b =0; System.out.println(a/b); }}
转载地址:http://gkpez.baihongyu.com/