throw
throw 语句用于抛出异常,例如 throw new EOFException()。
 
throws
当使用throw 语句抛出checked 异常后,可以不用捕获异常并处理,而是使用throws 语句传递异常给本方法的调用者,调用者根据自身情况对异常进行捕获或者继续传递异常给它的调用者,如下:
public void read () throws IOException(
xxx
throw new IOException();
}
当调用了包含throws checked 异常语句的方法后,可以用同样方式处理。
 
try/catch
如果打算捕获并处理异常,那么可以使用 try/catch 语句块,一般格式如下:
try{
xxx
}
catch (IOException e){
xxx
}
catch (Exception e){
xxx
}
在Java SE 7中,也可以合并多个catch语句,如下:
try{
xxx
}
catch (IOException e | Exception e){
xxx
}
如果在 try 语句块中的任何代码抛出了一个在 catch 语句块中捕获的异常类,那么程序将跳过 try 语句块的其余代码并且执行对应 catch 语句块中的代码。如果方法中的任何代码拋出了一个在 catch 语句块中没有声明的异常类型,那么这个方法就会立刻退出。
catch 语句块在处理异常时,可以对异常进行包装后重新抛出,如下:
try{
xxx
}
catch (SQLException e){
throw new ServletException ("xxxx") ;
}
 
finally
不管try 语句块是否抛出异常,甚至在try 语句块里有return 语句,finally 语句块中的代码最后都会被执行。它通常用来回收系统资源,如下:
InputStream in = ..
try{
xxx
}
finally{
in.close();
}
也可以带有catch 语句块,如下:
InputStream in = ..
try{
xxx
}
catch (IOException e){
xxx
}
finally{
in.close();
}
注意,当执行了System.exit()、JVM崩溃、当前线程被其他线程中断或者杀死,那么finally 语句块不会执行。
 
return
return 是用来退出当前方法,并返回一个值给调用者。
 
综合
看一个例子:
public class Demo {
public static int test() {
int x = 1;
try {
return ++x;
} catch (Exception e) {
e.printStackTrace();
} finally {
++x;
}
return x;
}
 
public static void main(String[] args) throws Exception {
int y = test();
System.out.println(y);
}
}
 
以上例子中,最终输出2。
 
原因是什么?
翻看官方的jvm规范就会把一切的谜团解开了:
If the try clause executes a return, the compiled code does the following:
Saves the return value (if any) in a local variable.
Executes a jsr to the code for the finally clause.
Upon return from the finally clause, returns the value saved in the local variable.
简单翻译下:
如果try语句里有return,那么代码的行为如下:
1.如果有返回值,就把返回值保存到局部变量中
2.执行jsr指令跳到finally语句里执行
3.执行完finally语句后,返回之前保存在局部变量表里的值
根据上面的说明就可以轻易地解释为什么是2了。
当执行到return ++x;时,jvm在执行完++x后会在局部变量表里另外分配一个空间来保存当前x的值。
注意,现在还没把值返回给y,而是继续执行finally语句里的语句。等执行完后再把之前保存的值(是2不是x)返回给y。所以就有了y是2不是3的情况。
其实这里还有一点要注意的是,如果你在finally里也用了return语句,比如return +xx。那么y会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。
 
查看Test.class的字节码我们同样也可以很轻松地知道为什么是2而不是3:
大概讲讲指令操作顺序:
iconst_1: 把常数1进栈 ---> istore_1: 栈顶元素出栈并把元素保存在本地变量表的第二个位置里(下标为1的位置里) ---> iinc 1, 1 : 本地变量表的第二个元素自增1 --->iload_1:第二个元素进栈 ---> istore_2:栈顶元素出栈并把元素保存在本地变量表的第2个位置里 ---> iinc 1, 1 : 本地变量表的第二个元素自增1 ---> iload_2:第二个元素进栈 (注意,此时栈顶元素为2)---> ireturn:返回栈顶元素。
后面的指令是要在2-7行出现异常时在跳到12行的,这个例子没出现异常,不用关注。
上面流程栈和本地变量表的情况如下图:
 
 
 
参考
https://www.cnblogs.com/averey/p/4379646.html

throw throws try catch finally return的更多相关文章

  1. 【Java】异常 —— throw, throws, try catch 相关内容

    嗯……面试考到了这个,又是一个如无意外 那么接下来就总结吧 一.什么是异常 程序运行过程中发生的异常事件. RuntimeException通常是因为编程员因为疏忽没有检查而引起的错误. 二.Exce ...

  2. Java throw throws try...catch区别

    java里的异常多种多样,这是一种非常有用的机制,它能帮助我们处理那些我们未知的错误,在java里,关于异常的有throw throws,还有一个try catch 程序块.接下来我们挨个看看这几个的 ...

  3. 异常处理(throw,throws,try,catch,finally)

    一.异常 1.定义:程序在运行时出现的不正确的情况. 2.由来:问题也是生活中的事物,也可以被Java描述,并被封装成对象. 其实就是Java对不正常情况进行描述后的对象体现. 3.划分:Java对于 ...

  4. final finalize finally throw throws try catch

    什么是finalize()方法 finalize()方法什么时候被调用 参见网址 析构函数(finalization)的目的是什么 final 和 finalize 的区别 final以下参见网址 f ...

  5. java异常处理之throw, throws,try和catch

    转自 http://blog.csdn.net/zhouyong80/article/details/1907799  程序运行过程中可能会出现异常情况,比如被0除.对负数计算平方根等,还有可能会出现 ...

  6. 顺平讲try catch finally throw throws(精华)

    try catch finally  有点像if else语句 还有像javascript的服务器执行成功后的回调函数,success:function(){ 进行处理 }; throws的意思是将异 ...

  7. throws、throw和try catch

    在学习代理模式的时候,编写动态生成代理类.java文件时,用try{}catch(){}捕获异常发现catch(Exception e)报错,得换成catch(Throwable e),然后又查了查两 ...

  8. java:异常机制(try,catch,finally,throw,throws,自定义异常)

    * String类中的格式化字符串的方法: * public static String format(String format, Object... args):使用指定的格式字符串和参数返回一个 ...

  9. try-catch和throw,throws的区别

    java里的异常多种多样,这是一种非常有用的机制,它能帮助我们处理那些我们未知的错误,在java里,关于异常的有throw throws,还有一个try catch 程序块.接下来我们挨个看看这几个的 ...

随机推荐

  1. 关于Chrome浏览器自动同步的问题

    Chrome浏览器是开发者最喜欢的浏览器,没有之一,那么公司办公和在家办公的话数据需要有一致性,这个时候就用到了浏览器的自动同步的功能 因为网络的问题,谷歌账户很难登录,基本需要VPN翻墙处理之后才能 ...

  2. 接口测试中postman环境和用例集

    postman的环境使用 postman里有环境的设置,就是我们常说的用变量代替一个固定的值,这样做的好处是可以切换不同的域名.不同的环境变量,不同的线上线下账户等等场景.下面就看下怎么用吧. 创建一 ...

  3. Java集合 Collection、Set、Map、泛型 简要笔记

    集合 什么是集合 概念 对象的容器,实现了对对象常用的操作 和数组的区别 数组长度固定,集合长度不固定 数组可以存储基本类型和引用类型,集合只能存储引用类型 位置 java.util.*; Colle ...

  4. 源码浅入浅出 Java ConcurrentHashMap

    从源码的角度深入地分析了 ConcurrentHashMap 这个线程安全的 HashMap,希望能够给你一些帮助. 老读者就请肆无忌惮地点赞吧,微信搜索[沉默王二]关注这个在九朝古都洛阳苟且偷生的程 ...

  5. spring-boot如何生成元数据与javaBean进行关联用作配置文件提示

    spring-boot如何生成元数据与javaBean进行关联用作配置文件提示 首先需要引入一个jar依赖包,以及一个maven plugin如下所示 <dependency> <g ...

  6. 封装Vue Element的dialog弹窗组件

    我本没有想着说要封装一个弹窗组件,但有同行的朋友在问我,而且弹窗组件也确实在项目开发中用的比较多.思前想后,又本着样式统一且修改起来方便的原则,还是再为大家分享一个我所封装的弹窗组件吧. 其实,并不是 ...

  7. Python | 详解Python中的协程,为什么说它的底层是生成器?

    今天是Python专题的第26篇文章,我们来聊聊Python当中的协程. 我们曾经在golang关于goroutine的文章当中简单介绍过协程的概念,我们再来简单review一下.协程又称为是微线程, ...

  8. vue实现pdf文件的在线预览

    我是通过 <iframe> 标签就可以满足我工作的 pdf预览需求 如果<iframe> 无法满足需求 , 可以使用pdf.js这个插件,功能强大. <iframe :s ...

  9. 简介&目录

    欢迎来到 MK 的博客鸭~ 这里会被我用来发一些OI算法.数据结构的学习笔记,各种游记和其他的一些内容,希望大家多多关照! ε≡٩(๑>₃<)۶ 然后目录就也放这里⑧:

  10. ZK集群源码解读

    1.1. 集群模式 1.1.1.   数据同步总流程 1.1.1.1. OBSERVING 1.1.1.2. FOLLOWING 1.1.1.3. LEADING 1.1.2. 领导选举 1.1.2. ...