异常就是程序运行中出现的错误
用到的类:
- Class.forName(“”)——该方法是,根据传入类的路径,找到类 new
- FileInputStream(“”)——该方法根据参数,找到一个存于本地磁盘的文件
Error类(错误)
- 程序不能试图捕获的严重错误
- 必须要立马解决
Exception(异常)
- 编译期异常(受检查异常)
① 写完代码,编译时出错
② 必须处理(捕获/抛出,都可以) - 运行时异常(非检查异常)
① 编译通过,运行时错误
② 编译时不会提示错误,不要求强制对其处理
解决方案
- 捕获(try catch)
① 程序中可能出现异常的代码都可以使用try catch包裹/环绕
② try {
可能出现异常的代码
}catch(异常类名 异常对象){
对异常的操作
}
③ 如果catch里的异常类与出现的异常不匹配,则会进行抛出处理
④ try中的代码若出现异常,仍会抛出,但会被catch中声明的同类型的异常所捕获
⑤ try内部,在出现异常的代码后的代码不再执行
⑥ 可以使用多个catch()捕获多个异常
⑦ finally是try体系中的一员,配合try使用;让某一段代码最后执行,且一定会执行;常用来释放资源
补充
-
return 和 finally:
顺序:遇到return,执行finally,再执行return返回值(若finally内有return执行该return,若没有,则执行遇到的return)返回值:
基本数据类型(包括字符串类型):若finally内无return,且在finally内改变将要返回的值,不过最终返回的值不会改变,仍是第一次遇到return时的值。
引用数据类型:若finally内无return,且在finally内改变将要返回的值,此时最终返回的值会改变,返回finally改变后的值。 -
多个catch并排捕获异常,一旦进入某个catch,就不再进入其他catch
-
方法显示throws 抛出异常,那么try catch该异常时,catch中可以写的异常类型是其本身或者父类或者是运行时异常,否则编译出错。
(我的理解是:由于java集成环境自动编译,所以代码写入后就会获得“编译时异常”的具体类型,所以使用 try.catch 时不能使用 catch 捕获其他类型的“编译时异常”(会报错))
- 抛出(throws)
① 如果程序中有异常要抛出时,需要在有异常的方法的参数列表后使用关键字throws
② 关键字throws后紧跟异常类名
③ 关键字throws可以跟多个异常类名,用“,”隔开
④ 当A方法调用有抛出异常的B方法时,A方法必须对同样的异常进行处理
⑤ 可以throws后在使用Exception类包括所有异常类
⑥ throw throws区别
a.Throws声明抛出的异常类;后跟类名;可以同时声明多个异常类名;放在方法参数列表后
b.Throw抛出异常对象;跟对象名;只能声明一个;放在方法体中
void test1() throws ClassNotFoundException{
Class.forName();
}
void test2() throws ClassNotFoundException,FileNotFoundException{
Class.forName();
new FileInputStream();
}
void test3() throws Exception{
Class.forName();
new FileInputStream();
}
主动抛出异常
throw
关键字主动抛出异常
throw new 异常类名();
Throw 后是运行时异常,可以不处理;是编译时异常必须处理
常用方法
- getMessage()
- getCause()
- printStackTrace()
- Exception(String message)
自定义异常
- 创建自定义异常类
- 继承某一个JDK提供的异常类
- 可以使用有参构造,将异常信息传给父类,父类打印;也可以重写getMessage()方法,当抛出异常时会默认调用getMessage()方法
- 在程序中使用
特点
- 程序抛出(Throws)异常,程序在抛出异常处停止运行
- Java程序对异常的默认处理是抛出异常
- 程序只能再同一时间抛出一种异常
- 当重写父类方法时,子类方法要小于等于父类使用throws抛出的异常
- 当父类方法没有使用throws抛出异常时,当子类重写该方法有异常时,只能使用try.catch
以后会使用日志框架,将重要信息保存下来
重要信息包括错误信息
练习
自定义一个学生类,属性有 姓名 年龄,如果用户在给学生年龄赋值时,年龄小于0或大于200 抛出一个AgeException。
AgeException类:
public class AgeException extends RuntimeException {
public AgeException(){
}
public AgeException(String str){
super(str);
}
// @Override
// public String getMessage(){
// return "年龄范围异常";
// }
}
Student类:
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age < 0 || age > 200){
throw new AgeException("年龄超出范围:" + age);
}else {
this.age = age;
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Main类:
public class Main {
public static void main(String[] args){
Student stu = new Student();
stu.setName("zs");
// try{
stu.setAge(300);
// return;
// }catch(AgeException ae){
// System.out.print("年龄超出范围");
// }finally{
// System.out.println(stu.getName());
// }
System.out.print(stu);
}
}