异常
- 异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。 在Java的异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类。异常类定义中包含了该类异常的信息和对异常进行处理的方法。
- 异常处理过程
-
抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE。
-
捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常。JRE在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。
try {
System.out.println(1 / 0);
}catch (Exception e){
System.out.println("出错了");
e.printStackTrace();
}
- 所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,异常又分为受检异常和不受检异常(运行时异常)
- Error是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题
运行时异常RuntimeException
- 派生于RuntimeException的异常,如被 0 除、数组下标越界、空指针等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大。 因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)
- 需要增加逻辑判断处理
受检异常CheckedException
- 这类异常在编译时就必须做出处理,否则无法通过编译
- 异常的处理方式有两种:使用“try/catch”捕获异常、使用“throws”声明异常
- try catch finally,可以有多个catch
try {
System.out.println("可能异常的语句");
System.out.println(1 / 0);
}catch (Exception e){
System.out.println("出错了");
//e.printStackTrace();
}finally {
System.out.println("总算结束了");
}
- 读文件
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class TestReadFile {
public static void main(String[] args) {
FileReader fileReader = null;
try {
fileReader = new FileReader("D:\\data\\shuihu.txt");
char c1 = (char)fileReader.read();
System.out.println(c1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) { //多个异常,子类在前,父类在后
e.printStackTrace();
}finally {
if(fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
throws
- 当CheckedException产生时,不一定立刻处理它,可以再把异常throws出去,
- 如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。 如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class TestThrow {
public static void main(String[] args) {
String path = "D:\\data\\shuihu.txt";
//处理异常,或者在方法后继续标记抛出异常
try {
readFile(path);
} catch (IOException e) {
e.printStackTrace();
}
}
static void readFile(String path) throws IOException {
FileReader fileReader = new FileReader(path);
char c1 = (char)fileReader.read();
System.out.println(c1);
if(fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
自定义异常
- 自定义异常类如果继承Exception类,则为受检查异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常RuntimeException类。
- 习惯上,自定义异常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器。
public class TestDefinedException {
public static void main(String[] args) {
Person p = new Person();
p.setAge(10000);
p.setName("高尔基 西莫维奇·彼什科夫");
}
}
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
if(age < 0 || age > 130){
//运行时异常
throw new IllegalAgeException("年龄有误");
}else{
this.age = age;
}
}
public String getName() {
return name;
}
public void setName(String name) {
if(name.length()>10){
try {
//Name的受检异常,必须trycatch或方法后标记抛出
throw new IllegalNameException("名字太长");
} catch (IllegalNameException e) {
e.printStackTrace();
}
}else {
this.name = name;
}
}
}
class IllegalAgeException extends RuntimeException{
/*
运行时异常
*/
public IllegalAgeException(){
}
public IllegalAgeException(String info){
super(info);
}
}
class IllegalNameException extends Exception{
public IllegalNameException(){}
public IllegalNameException(String info){
super(info);
}
}