目录
2.2 所有的RuntimeException及子类都属于运行时异常
2.4.1 在方法声明的位置使用throws关键字,抛给上一级
一、基本概念
1.1 什么是异常?
程序执行过程中发生了不正常的情况,而这种不正常的情况叫做异常,以类的形式存在
1.2 java提供的异常处理机制有什么作用?
java把该异常信息打印输出到控制台,供程序员参考,进一步修改程序,让程序更加健壮
1.3 java语言中异常以什么形式存在?
异常在java中以类的形式存在,每一个异常类都可以创建异常对象
例1:
NumberFormatException nfe = new NumberFormatException("数字格式化异常");
System.out.println(nfe);
NullPointerException nullPointerException = new NullPointerException("空指针异常");
System.out.println(nullPointerException);
二、异常处理机制
2.1 所有Exception的直接子类都叫做编译时异常
那编译时异常是在编译阶段发生的吗?
不是。这个地方是指的程序员编写程序阶段,如果不处理,编译器会报错
2.2 所有的RuntimeException及子类都属于运行时异常
运行时异常在编写程序阶段,可以选择处理也可以选择不处理
2.3 编译时异常与运行时异常的区别与相同点
区别:
编译时异常发生的概率高,运行时异常发生的概率低
加入java中对异常没有划分,则程序将会是绝对安全的,但程序员编写程序太累,代码到处都是处理异常的代码
共同点:
所有异常发生时都会new对象,
所有异常发生在运行阶段,编译阶段异常是不会发生的
2.4 异常处理的方式
2.4.1 在方法声明的位置使用throws关键字,抛给上一级
一般不建议在main方法上使用throws,若异常发生则抛给JVM,导致终止程序,一般main方法中的异常建议使用try..catch捕捉
public class Test {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("amin begin");
m1();
System.out.println("main over");
}
private static void m1() throws FileNotFoundException {
System.out.println("m1 begin");
m2();
System.out.println("m2 over");
}
private static void m2() throws FileNotFoundException {
System.out.println("m2 begin");
m3();
System.out.println("m2 over");
}
private static void m3() throws FileNotFoundException {
new FileInputStream("D:/course");
}
}
2.4.2 使用try..catch语句进行异常捕捉
注意!try语句块中某一行出现异常,该行后面的代码不会执行
try...catch捕捉异常后,后续代码可以执行(指的是try...catch之外的代码)
public class Test {
public static void main(String[] args) {
System.out.println("main begin");
try {
m1();
System.out.println("看看是否运行");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("main over");
}
private static void m1() throws FileNotFoundException {
System.out.println("m1 begin");
m2();
System.out.println("m2 over");
}
private static void m2() throws FileNotFoundException {
System.out.println("m2 begin");
m3();
System.out.println("m2 over");
}
private static void m3() throws FileNotFoundException {
new FileInputStream("D:/course");
}
}
三、异常对象的常用方法
3.1 获取异常简单的描述信息
NullPointerException e = new NullPointerException("空指针异常");
System.out.println( e.getMessage());
3.2 打印异常追踪的堆栈信息(建议使用)
NullPointerException e = new NullPointerException("空指针异常");
e.printStackTrace();
System.out.println("helloword");
值得说明的是,打印堆栈信息可能在打印“HelloWord”下面,因为打印堆栈信息是其他线程(异步线程)在后台执行的
四、finally 字句的使用
- finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常
- finally子句必须和try一起出现,不能单独编写
- finally语句经常使用在完成资源的释放或关闭,因为finally中的代码比较有保障
下图代码中,即使在try中添加了return,finally语句依然会执行
try{
System.out.println("try....");
return;
}finally {
System.out.println("finally....");
}
其他易错点可以查看下面这一篇博客
Java中finally的易错点_我爱布朗熊的博客-CSDN博客
但是在try语句中退出JVM之后,finally语句中的代码就不会执行了
五、自定义异常
第一步:编写一个类继承Exception或RuntimeException
发生的概率高就继承Exception,发生的概率低就继承RuntimeException
第二步:提供一个无参,一个String参数的有参
public class MyException extends Exception {
public MyException() {
}
public MyException(String msg) {
super(msg);
}
}
public class Test {
public static void main(String[] args) {
MyException e = new MyException("用户名不可为空");
e.printStackTrace();
}
}
六、异常与方法覆盖
重写之后的方法不能比重写之前的方法抛出更更多(更宽泛)的异常,可以更少
比如下端这段代码,出现了报错现象,因为父类对应的方法并没有异常,而子类重写之后的方法多了异常,最终导致出现错误