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. Charles 断点修改Response

    前言: 我们可以通过map功能进行重定向,但如果同一个域名进行的是不同请求与返回.此时map在这里就不适用了. 我们可以通关对某一请求进行断点,在进行修改请求或者返回.这样就可以满足我们的需求了. 一 ...

  2. 前端 的一些css的写法

    攒一下小技巧 1.select 默认提示但是不显示在选择列表中 <option selected="selected" disabled="disabled&quo ...

  3. /usr/bin/ld: cannot find -lcrypto

    当我们使用openssl里边的函数的时候,需要链接crypto的库 如果找不到,加一个软链接,如下: ln -s /usr/lib64/libcrypto.so.1.1 /usr/lib64/libc ...

  4. 后端队列生成pdf,发送到邮箱

    最开始可以先将你想要的pdf模板写好先,如testPage <!DOCTYPE html> <html> <head> <meta http-equiv=&q ...

  5. ES6--let,解构赋值,promise && ES7--async

    ES-->IE10.Google.火狐 ES6 let 声明的关键字 不能重复声明 块级作用域 <input type="button" value="1&q ...

  6. jq cdn地址

    百度CDN支持版本2.0.3, 2.0.2, 2.0.1, 2.0.0,1.11.1, 1.10.2, 1.10.1, 1.10.0, 1.9.1, 1.9.0, 1.8.3, 1.8.2, 1.8. ...

  7. 浅谈 FTP、FTPS 与 SFTP

    无论是网盘还是云存储,上传都是一项很简单的操作.那些便捷好用的上传整理工具所用的 FTP 协议到底是什么意义,繁杂的模式又有何区别? 二狗子最近搭建了一个图片分享网站,每天都有好多人在他的网站上传许多 ...

  8. Android 设备指纹

    Android唯一识别号(设备指纹)的生成及原理 https://blog.csdn.net/xiechengfa/article/details/70049409?utm_source=itdada ...

  9. Google Kick Start Round G 2019

    Google Kick Start Round G 2019 Book Reading 暴力,没啥好说的 #include<bits/stdc++.h> using namespace s ...

  10. jQuery 如何实现 模糊搜索

    如何实现 模糊搜索 当我们浏览网页的时候,通常能看到搜索栏,这大大的提高了我们获取数据的目的性.那如何去实现一个简单的模糊搜索 框呢,以下案例获取能给你一点思路. 以下案例,可以实现当按键按下时,自动 ...