1. 程序的异常
严重问题:Error 不处理,问题严重,比如内存溢出
问题:Exception:
编译器问题:不是运行期RuntimeException的异常,必须进行处理,不处理将不能通过编译
运行期问题:RuntimeException 这种问题也不处理,程序的严谨性问题
如果程序出现了问题,我们没有处理,虚拟机将默认进行处理:把异常问题,出现的原因输出在控制台,同时结束程序
1.1 try...catch...finally处理格式
try { //可能出现问题的代码,代码量越少越好,虚拟机需要开辟新的问题处理这个问题 }catch(异常名称) { //针对问题的处理 }finally { //释放资源 } // 变形格式 try { //可能出现问题的代码,try问题出现以后,将会去catch里面查找,但是不能继续执行try里面的代码 }catch(异常名称) { //异常名称写成Exception可以接收所有的异常,能明确尽量明确,针对问题的处理,需要有处理方式 }
例如:
public static void main(String[] args) { int a = 20; int b = 0; try { System.out.println(a / b); }catch(ArithmeticException s) { System.out.println("除数不能为0"); } System.out.println("over"); }
JDK7异常处理新特性:
public static void method2() { int a = 0; int b = 0; int[] arr = {1, 2, 3}; try { System.out.println(a / b); System.out.println(arr[3]); }catch(ArithmeticException | ArrayIndexOutOfBoundsException s){ System.out.println("有问题"); } System.out.println("over");
注意:异常必须是同级关系,不能够是继承关系,并且所有的异常执行同一种操作
异常的几个常用方法:
public String getMessage():返回异常的消息字符串
public String toString():返回throwable的简短描述,将由一下字符串拼接而成:
此对象的类的名称(全路径名)
": "冒号和一个空格
调用此对象getLocalizedMessage()方法的结果
public String getLocalizedMessage():创建throwable的本地化描述,子类可以重写此方法,以便生成特定语言环境的消息,对于不重写此方法的子类,将默认返回与getMessage()的结果
void printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回void
void printStackTrace(PrintStream s):通常用该方法将异常的内容存储到日志文件中,以便日后查看
public static void main(String[] args) { String s = "2014-01"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { Date d = sdf.parse(s); System.out.println(d); } catch (ParseException e) { System.out.println(e.getMessage()); System.out.println(e.toString()); e.printStackTrace(); } }
finally:finally控制的语句一定会得到执行,但是如果执行finally之前jvm退出,将不能执行
finally主要用于释放资源,在IO流和数据库的操作中会经常遇到
final:最终的意思,可以修饰类,成员变量,成员方法
修饰类:类不能够被继承
修饰变量:该变量是常量
修饰方法:方法不能够被重写
finalize:是Object类的一个方法,用于垃圾回收。
1.2 throws处理格式
特点:自身不能处理或者没有权限处理,抛出后是编译器的异常必须要处理,运行期可以不处理
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 = "2015-11-20"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//不能处理或者没有权限处理 Date d = sdf.parse(s); }
1.3 throw以及与throws的区别
throws:
用在方法声明后面,后面跟的是异常的名称
可以跟多个异常类名称,用逗号隔开
表示抛出异常,由该方法的调用者来处理这个异常
throws表示出现异常的一种可能性,并不一定会发生这些异常
throw:
用在方法体中,跟的是异常的对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定是抛出了某种异常
public static void main(String[] args) { method1(); try { method2(); } catch (Exception e) { e.printStackTrace(); } } public static void method1() { int a = 10; int b = 0; if (b == 0) { throw new ArithmeticException(); }else { System.out.println(a / b); } } public static void method2() throws Exception { int a = 10; int b = 0; if(b == 0) { throw new Exception(); }else { System.out.println(a / b); } }
throws和try到底应该用哪个:
如果后续程序需要继续运行就执行try
如果后续程序不需要继续运行就执行throws
面试题:如果catch里面由return语句,那么finally里面的代码是否会执行,如果会,请问在return 前还是在return 后:会,前,但是return 的返回路径已经确定,准确的说finally在return 的中间
public static void main(String[] args) { System.out.println(getInt()); } public static int getInt() { int a = 10; try { System.out.println(a / 0); a = 20; }catch(ArithmeticException e) { System.out.println("出错啦"); a = 30; return a; }finally { System.out.println("到底在哪里呢"); a = 40; } return a; } 程序运行结果: 出错啦 到底在哪里呢 30