100次浏览 发布时间:2024-11-15 08:20:36
Throwable 类是 Java 语言中所有错误或异常的超类。当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。
含义:异常的英文单词是exception,字面翻译就是“意外、例外”的意思,也就是非正常情况。事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误。(开发过程中的语法错误和逻辑错误不是异常)
Error:是Throwable的子类,用于指示合理的应用程序不应该试图捕获的严重问题。是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。
Exception 异常主要分为两类
【注】检查异常指:编译器在编译期间要求必须得到处理的那些异常,你必须在编译期处理了。最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
异常的处理方式:
try...catch关键字:使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。真正的将异常给处理掉了
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
// try...catch 的语法如下
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}
try {
// String line = null;
// String line = "";
String line = "abc";
//当JVM执行程序出现了某个异常时就会实例化这个异常并将其抛出
//如果该异常没有被异常处理机制控制,则JVM会将异常隐式抛出当方法外(这里是main方法外)
System.out.println(line.length());
System.out.println(line.charAt(0));
System.out.println(Integer.parseInt(line));
//若try语句块中某句话出错了,则剩下的代码都不会执行!
System.out.println("!!!!!!!!!!!!!!!!");
}catch(NullPointerException e){
System.out.println("出现了空指针!");
//catch可以定义多个,当try中不同的异常有不同处理办法时可分开捕获并处理
}catch(StringIndexOutOfBoundsException e){
System.out.println("出现了下标越界!");
}
//若某些异常的处理方式相同时,可以合并在一个catch来处理
try {
String line = "abc";
//当JVM执行程序出现了某个异常时就会实例化这个异常并将其抛出
//如果该异常没有被异常处理机制控制,则JVM会将异常隐式抛出当方法外(这里是main方法外)
System.out.println(line.length());
System.out.println(line.charAt(0));
System.out.println(Integer.parseInt(line));
//若try语句块中某句话出错了,则剩下的代码都不会执行!
System.out.println("!!!!!!!!!!!!!!!!");
}catch(NullPointerException|StringIndexOutOfBoundsException e){
System.out.println("出现了空指针或下标越界并处理了!");
//可以在下面catch超类异常来捕获并处理这一类异常。
}catch(Exception e){
System.out.println("反正就是出了个错");
}
return:当代码中出现return时,一定是finally语句块执行完成之后,才会去执行相应的return代码。无论这条return语句放在什么位置。
finally关键字:无论是否发生异常,finally代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。真正的将异常给处理掉了
// try...catch...finally 的语法如下
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
//不管try里面是否异常,都会执行finally中的代码块
try{
String line = null;
System.out.println(line.length());
return; //----------------------上面return执行流程图很好的解释了
}catch(Exception e){
System.out.println("出错了!");
}finally{
System.out.println("finally中的代码执行了!");
}
自动关闭特性,JDK7之后,java提供了一个新的特性:自动关闭。旨在IO操作中可以更简洁的使用异常处理机制完成最后的close操作。【注意】语法中可在try的"()"中定义的并初始化的对象必须实现了java.io.AutoCloseable接口,否则编译不通过.
// 自动关闭 语法:
try(
定义需要在finally中调用close()方法关闭的对象.
){
IO操作
}catch(XXXException e){
...
}
//下面代码是编译器认可的,而不是虚拟机。
// 编译器在编译上述代码后会在编译后的class文件中改回原本的写法
try(
FileOutputStream fos = new FileOutputStream("fos.dat");
){
fos.write(1);
} catch (IOException e) {
e.printStackTrace();//向控制台输出当前异常的错误信息
}
throws和thow关键字:如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
【注】throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由方法去处理异常,真正的处理异常由此方法的上层调用处理。
throw通常下面两种情况我们主动对外抛出异常:throw关键字的一个非常重要的作用就是 异常类型的转换.
throws当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。允许throws后面跟着多个异常类型;处理手段有下面两种方式:
public class Person {
private int age;
public int getAge() {
return age;
}
//当一个方法使用throws声明异常抛出时,调用此方法的代码片段就必须处理这个异常
public void setAge(int age) throws Exception {
if(age<0 || age>100){
//使用throw对外抛出一个异常
// throw new RuntimeException("年龄不合法!");
//除了RuntimeException之外,抛出什么异常就要在方法上声明throws什么异常
throw new Exception("年龄不合法!");
}
this.age = age;
}
}
// 【注意】 永远不应当在main方法上使用throws!!
try {
Person p = new Person();
/*
当我们调用一个含有throws声明异常抛出的方法时,编译器要求
我们必须添加处理异常的手段,否则编译不通过.而处理手段有两种
1:使用try-catch捕获并处理异常
2:在当前方法上继续使用throws声明该异常的抛出
具体用哪种取决于异常处理的责任问题
*/
p.setAge(100000);//典型的符合语法,但是不符合业务逻辑要求
System.out.println("此人年龄:"+p.getAge()+"岁");
} catch (Exception e) {
e.printStackTrace();
}
子类重写超类含有throws声明异常抛出的方法时对throws的几种特殊的重写规则
public class ThrowsDemo {
public void dosome()throws IOException, AWTException {}
}
class SubClass extends ThrowsDemo{
// public void dosome()throws IOException, AWTException {}
//可以不再抛出任何异常
// public void dosome(){}
//可以仅抛出部分异常
// public void dosome()throws IOException {}
//可以抛出超类方法抛出异常的子类型异常
// public void dosome()throws FileNotFoundException {}
//不允许抛出额外异常(超类方法中没有的,并且没有继承关系的异常)
// public void dosome()throws SQLException {}
//不可以抛出超类方法抛出异常的超类型异常
// public void dosome()throws Exception {}
}
可检测异常,非检测异常
try {
String str = "abc";
System.out.println(Integer.parseInt(str));
} catch (NumberFormatException e) {
//异常最常用的方法,用于将当前错误信息输出到控制台
e.printStackTrace();
//获取错误消息.记录日志的时候或提示给用户可以使用它
String message = e.getMessage();
System.out.println(message);
}
自定义异常类
注意以下问题:
//自定义 异常类 继承 Exception 并且重写里面的构造方法
public class IllegalAgeException extends Exception{
public IllegalAgeException() {
}
public IllegalAgeException(String message) {
super(message);
}
public IllegalAgeException(String message, Throwable cause) {
super(message, cause);
}
public IllegalAgeException(Throwable cause) {
super(cause);
}
public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}