标签:Exception Java 16 try finally catch 异常 public
异常起步
public class TestUtil {
public static void main(String[] args) {
excepTest1();
excepTest2();
System.out.println("main 方法没有捕获异常,不会继续执行");
}
public static void excepTest1(){
/**
* 发生异常时,会启用异常处理机制,首先创建一个异常对象
* 异常处理机制会从当前方法开始查找看谁 “捕获” 了这个异常,
* 当前方法没有就查看上一层,直到 main 方法,
* 如果也没有,就使用默认机制,即输出异常栈信息并退出
*/
String str = "abc";
try {
int num = Integer.parseInt(str);
System.out.println("如果异常,try 语句内,异常点后的代码不会执行");
System.out.println(num);
} catch (NumberFormatException e1){
System.err.println("参数:"+ str +",不是有效数字");
e1.getMessage();
e1.getCause();
e1.printStackTrace();
} catch (Exception e2){
/**
* 异常处理机制将根据抛出的异常类型找第一个匹配的 catch 块,
* (Java 7 开始,多个异常之间可以用“|”操作符,但注意异常之间不能有父子关系)
* 找到后,执行catch块内的代码,不再执行其他 catch 块,
* 如果没有找到,会继续到上层方法中查找。
* 需要注意的是,如果抛出的异常类型是 catch 中声明异常的子类也算匹配(多态)
*/
System.err.println("异常类型不是 NumberFormatException 才会执行");
throw e2;
} finally {
System.out.println("不管有没有异常,一定执行");
}
System.out.println("当前有捕获异常,方法会继续执行");
}
public static void excepTest2(){
String str = "abc";
int num = Integer.parseInt(str);
System.out.println("当前没有捕获异常,方法不会继续执行,向上级方法查找异常捕获");
System.out.println(num);
}
/**
* throws 跟在方法的括号后面,可以声明多个异常,以逗号分隔
* 主要用于在父类方法中声明可能(包括子类)抛出的异常
* @throws Exception
*/
public static void excepTest3() throws Exception {
try {
} catch (Exception e){
e = new Exception(); // 注释该行,可以去掉方法后的 throws
throw e;
}
}
}
异常处理方式
catch
捕获
异常处理机制将根据抛出的异常类型找第一个匹配的catch块,找到后,执行catch块内的代码,不再执行其他catch块,如果没有找到,会继续到上层方法中查找。
需要注意的是,抛出的异常类型是catch中声明异常的子类也算匹配,所以需要将最具体的子类放在前面,如果基类Exception放在前面,则其他更具体的catch代码将得不到执行。
throw
抛出
return 代表正常退出,throw 代表异常退出。
return 的返回位置是确定的,就是上一级调用者;
throw 后执行哪行代码则经常是不确定的,由异常处理机制动态确定。
- try-with-resources
对于一些使用资源的场景,比如文件和数据库连接,典型的使用流程是首先打开资源,最后在finally语句中调用资源的关闭方法,针对这种场景,Java 7开始支持一种新的语法,称之为try-with-resources,这种语法针对实现了java.lang.AutoCloseable
接口的对象。
资源的声明和初始化放在try语句内,不用再调用finally,在语句执行完try语句后,会自动调用资源的close()方法。资源可以定义多个,以分号分隔。
在Java 9之前,资源必须声明和初始化在try语句块内,Java 9去除了这个限制,资源可以在try语句外被声明和初始化,但必须是final的或者是事实上final的(即虽然没有声明为final但也没有被重新赋值)
try(AutoCloseable autoClose = new FileInputStream("hello")){
//
}
finally
finally 内的代码不管有无异常发生,都会执行。
- 如果没有异常发生,在 try 内的代码执行结束后执行
- 如果有异常发生且被 catch 捕获,在 catch 内的代码执行结束后执行
- 如果有异常发生但没被 catch 捕获,则在异常被 throw 抛给上层之前执行
- 如果在 try 或者 catch 语句内有 return 语句,则 return 语句在 finally 语句执行结束后才执行,但 finally 中并不能改变返回值(可以理解为返回值存储在返回值存储器中,finally 的操作不会改变返回值存储器中的值)
- 如果 finally 中有 return,不仅会覆盖 try 和 catch 内的返回值,还会掩盖 try 和 catch 内的异常,就像异常没有发生一样,应该避免在 finally 中使用 return 语句或者抛出异常
异常体系
Throwable
Throwable是所有异常的基类,它有两个子类:Error 和 Exception。
Error 用来指示运行时环境发生的错误,错误一般发生在严重故障时,它们在Java程序处理的范畴之外,Java 程序通常不捕获错误。
方法 | 说明 |
---|---|
public String getMessage() | 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。 |
public Throwable getCause() | 返回一个 Throwable 对象代表异常原因。 |
public String toString() | 返回此 Throwable 的简短描述。 |
public void printStackTrace() | 将此 Throwable 及其回溯打印到标准错误流。。 |
public StackTraceElement[] getStackTrace() | 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 |
public Throwable fillInStackTrace() | 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。 |
异常分类
Exception 有两个主要的子类:IOException 类和 RuntimeException 类。
- RuntimeException 运行时异常
运行时异常可以在编译时被忽略。
- RuntimeException 以外都是检查性异常
检查性异常在编译时不能被简单地忽略,否则会编译错误。
自定义异常
一般是继承 Exception 或者它的某个子类。
// 自定义异常类,继承Exception类
public class InsufficientFundsException extends Exception {
// 此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱
private double amount;
public InsufficientFundsException(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
标签:Exception,Java,16,try,finally,catch,异常,public 来源: https://www.cnblogs.com/knhap/p/16290086.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。