异常机制
1.异常?
异常指程序运行中出现的不期而至的各种状况:文件找不到,网络连接失败等
异常发生在程序运行期间,它影响了正常的程序执行流程
-
检查性异常:最具代表性,是用户错误或问题引起的异常,无法被程序员预见。例如打开一个不存在的文件时
-
运行时异常:可被避免,运行时异常可以在编译时被忽略
-
错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中可以被忽略。例如:栈溢出时,一个错误就发生了,编译时检查不到
2.异常的体系架构
-
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为异常的超类。
-
异常类分为两大类:错误Error和异常Exception
-
Error
- Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
- Java虚拟机运行错误,当JVM不再继续执行操作所需的内存资源时,出现OutOfMemoryError.这些异常发生时,Java虚拟机(JVM)一般选择线程终止
- Java虚拟机试图执行应用时,如类定义错误、链接错误。这些错误不可查,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况
-
Exception
- 重要的子类RuntimeException(运行时异常)
- ArrayIndexOutOfBoundsException
- NullPointerException
- ArithmeticException
- MissingResourceException
- ClassNotFound
这些一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能地避免这类异常的发生
- 重要的子类RuntimeException(运行时异常)
-
区别:Error通常是致命的错误,是程序无法控制和处理的,Java虚拟机一般选择终止线程;Exception通常情况下可以被程序处理的。
3.异常处理机制
-
抛出异常
-
捕获异常
-
关键字:try catch finally throw throws
public class Demo11 { public static void main(String[] args) { int a=11; int b=0; try{ //监控区域 System.out.println(a/b); }catch(ArithmeticException e){ System.out.println("程序异常,变量b不能为0"); }finally{ System.out.println("finally"); } /* 可以不需要finally, */ } }
public class Demo11 { public static void main(String[] args) { try { new Demo11().demo11(2,0); } catch (ArithmeticException e) { e.printStackTrace(); } finally { } } void demo11(int a,int b)throws ArithmeticException{ if(b==0){ throw new ArithmeticException(); } } }
public class Demo12 {
public static void main(String[] args) {
int a=11;
int b=0;
try{
new Demo11().a();
}catch(Throwable e){
System.out.println("程序异常");
}finally{
System.out.println("finally");
}
}
void a(){
b();
}
void b(){
a();
}
}
public class Demo13 {
public static void main(String[] args) {
int a=11;
int b=0;
try{
if(b==0)
throw new ArithmeticException();
//主动抛出异常,一般在方法中使用
System.out.println(a/b);
}catch(Error e) {
System.out.println("Error");
}catch(Exception e){
System.out.println("Exception");
}finally{
System.out.println("finally");
}
}
}
//Exception
//ctrl+alt+t 快捷键的使用
4.自定义异常
- Java内置异常类可以描述在编程时出现的大部分异常情况。用户 可自定义异常,只需要继承Exception类即可
- 步骤:
- 1.创建自定义异常类
- 2.在方法中通过throw关键字抛出异常对象
- 3.可用try-catch捕获并处理异常;或者throws关键字指明抛出给方法调用者的异常,继续下一步操作
- 4.在出现异常方法的调用者中捕获并处理异常
public class Demo12 {
public static void main(String[] args) {
try {
Test.test(22);//数字可换
} catch (MyException e) {
System.out.println("MyException:"+e);
}
}
}
class Test{
static void test(int a) throws MyException {
System.out.println("传递的参数是"+a);
//定义如果参数超过10,异常
if(a>10){
throw new MyException(a);//抛出
}
System.out.println("正确");
}
}
class MyException extends Exception{
private int detail;
MyException(int a){
this.detail=a;
}
//alt+insert 快捷键
//toString 打印异常信息
public String toString() {
return "MyException{" +
"detail=" + detail +
'}';
}
}
5.小结
- 处理运行异常时,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch块后面可再加catch(Exception)来处理可能遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理(alt+enter 针对红色波浪线出错代码)
- 尽可能去处理,切忌简单调用printStackTrace()去打印出输出
- 尽量用finally去释放占用的资源,(io流,Scanner)