JAVA常用知识总结(一)
try catch finally 的详细用法:
public static int testBasic(){
int i = 1;
try{
i++;
System.out.println("try block, i = "+i);
}catch(Exception e){
i ++;
System.out.println("catch block i = "+i);
}finally{
i = 10;
System.out.println("finally block i = "+i);
}
return i;
}
此代码为常规代码,会按照顺序执行,先执行try内代码段,没有异常的话进入finally,最后返回,那么输出如下:
try block, i = 2
finally block i = 10 最终返回 i=10;
这个没有问题,如果我们把return语句放入try catch里又会怎么样呢
public static int testBasic(){
int i = 1;
try{
i++;
System.out.println("try block, i = "+i);
return i;
}catch(Exception e){
i ++;
System.out.println("catch block i = "+i);
return i;
}finally{
i = 10;
System.out.println("finally block i = "+i);
}
}
输出结果为:
try block, i = 2
finally block i = 10 最终返回 i = 2;
代码顺序执行从try到finally,由于finally是无论如何都会执行的,所以try里的语句并不会直接返回。在try语句的return块中,return返回的引用变量并不是try语句外定义的引用变量i,而是系统重新定义了一个局部引用i’,这个引用指向了引用i对应的值,也就是2,即使在finally语句中把引用i指向了值10,因为return返回的引用已经不是i,而是i',所以引用i的值和try语句中的返回值无关了。
但是,这只是一部分,如果把i换成包装类型而不是基本类型呢,来看看输出结果怎样,示例如下:
public static List<Object> testWrap(){
List<Object> list = new ArrayList<>();
try{
list.add("try");
System.out.println("try block");
return list;
}catch(Exception e){
list.add("catch");
System.out.println("catch block");
return list;
}finally{
list.add("finally");
System.out.println("finally block ");
}
}
输出结果如下:
try block
finally block 最终返回 i = [try, finally]
可以看到,finally里对list集合的操作生效了,这是为什么呢。我们知道基本类型在栈中存储,而对于非基本类型是存储在堆中的,返回的是堆中的地址,因此内容被改变了。
好了,现在我们在finally里加一个return,看看语句是从哪里返回的
public static int testBasic(){
int i = 1;
try{
i++;
System.out.println("try block, i = "+i);
return i;
}catch(Exception e){
i ++;
System.out.println("catch block i = "+i);
return i;
}finally{
i = 10;
System.out.println("finally block i = "+i);
return i;
}
}
输出结果如下:
try block, i = 2
finally block i = 10
main test i = 10
可以看到,是从finally语句块中返回的。可见,JVM是忽略了try中的return语句。但IDE中会对finally中加的return有黄色警告提示,这是为什么呢,在try里加入一行会执行异常的代码,如下:
public static int testBasic(){
int i = 1;
try{
i++;
int m = i / 0 ;
System.out.println("try block, i = "+i);
return i;
}catch(Exception e){
i ++;
System.out.println("catch block i = "+i);
return i;
}finally{
i = 10;
System.out.println("finally block i = "+i);
return i;
}
}
打印结果如下:
catch block i = 3
finally block i = 10
main test i = 10
可以看到,因为finally中有return语句,try、catch中的异常被消化掉了,屏蔽了异常的发生,这与初期使用try、catch的初衷是相违背的,因此编译器也会提示警告。
那如果在finally中有异常发生,会对try、catch中的异常有什么影响呢?
public static int testBasic(){
int i = 1;
try{
i++;
Integer.parseInt(null);
System.out.println("try block, i = "+i);
return i;
}catch(Exception e){
String.valueOf(null);
System.out.println("catch block i = "+i);
return i;
}finally{
i = 10;
int m = i / 0;
System.out.println("finally block i = "+i);
}
}
这里我们在try、catch里强行加上异常语句,打印结果如下:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at tryandcatch.TryAndCatch.testBasic(TryAndCatch.java:25)
at tryandcatch.TryAndCatch.main(TryAndCatch.java:45)
这个提示表示的是finally里的异常信息,也就是说一旦finally里发生异常,try、catch里的异常信息即被消化掉了,也达不到异常信息处理的目的。
总结以上测试:
1、finally语句总会执行
2、如果try、catch中有return语句,finally中没有return,那么在finally中修改除包装类型和静态变量、全局变量以外的数据都不会对try、catch中返回的变量有任何的影响
3、尽量不要在finally中使用return语句,如果使用的话,会忽略try、catch中的返回语句,也会忽略try、catch中的异常,屏蔽了错误的发生
4、finally中避免再次抛出异常,一旦finally中发生异常,代码执行将会抛出finally中的异常信息,try、catch中的异常将被忽略
所以在实际项目中,finally常常是用来关闭流或者数据库资源的,并不额外做其他操作。
JAVA常用知识总结(一)的更多相关文章
- JAVA常用知识总结(十三)——数据库(三)
Mysql的主键选择(主键自增,UUID,snowflake)? 使用自增长做主键的优点:1.很小的数据存储空间2.性能最好3.容易记忆使用自增长做主键的缺点:1.如果存在大量的数据,可能会超出自增长 ...
- JAVA常用知识总结(七)——Spring
如果一个接口有2个不同的实现, 如何Autowire某一个指定的实现? 1.通过增加@Qualifier(实现类的名字): @Autowired @Qualifier("GirlStuden ...
- JAVA常用知识总结(六)——Mybatis
为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里? Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取, ...
- JAVA常用知识总结(三)——JAVA虚拟机
先附一张JAVA虚拟机内存结构图: 其中JAVA虚拟机的线程问题<为什么JAVA虚拟机分为线程共享和非线程共享?>一文中已经有详细介绍,本文从面试中常问的一些JAVA虚拟机问题出发,主要从 ...
- JAVA常用知识总结(十四)——Servlet
Servlet属于线程安全的吗? Servlet不是线程安全的! 谈谈转发和重定向的区别 请求转发: request.getRequestDispatcher("/king_l2lu.jsp ...
- JAVA常用知识总结(十一)——数据库(一)
项目中用到的不常见sql语法 1:空值不在前的排序 select a.* from WZX_SCZY A order by SCZY_START_TIME desc nulls last (不加nul ...
- JAVA常用知识总结(九)——线程
sleep和wait的区别? sleep()来自Thread类,和wait()来自Object类.调用sleep()方法的过程中,线程不会释放对象锁.而 调用 wait 方法线程会释放对象锁 slee ...
- JAVA常用知识总结(八)——计算机网络
GET 和 POST 的区别? get参数通过url传递,post放在request body中. get请求在url中传递的参数是有长度限制的,而post没有. get比post更不安全,因为参数直 ...
- JAVA常用知识总结(五)——Linux
简单介绍一下 Linux 文件系统? 在Linux操作系统中,所有被操作系统管理的资源,例如网络接口卡.磁盘驱动器.打印机.输入输出设备.普通文件或是目录都被看作是一个文件. 也就是说在LINUX系统 ...
- JAVA常用知识总结(四)——集合
先附一张java集合框架图 下面根据面试中常问的关于集合的问题进行了梳理: Arraylist 与 LinkedList 有什么不同? 1. 是否保证线程安全: ArrayList 和 LinkedL ...
随机推荐
- Struts2中Action接收参数
Struts2中Action接收参数的方法主要有以下三种: Struts2中Action接收参数的方法主要有以下三种: 1.使用Action的属性接收参数: a.定义:在Action类中定义属 ...
- activity四种状态
finish() 使得activity死掉 activity 部分可见进入pause状态.全部不可见进入stop状态 .界面从死亡——运行(启动) MainAdctivity.onCreate.on ...
- mysql 数据库连接
1.需要mysql驱动包:mysql-connector-java-5.1.7-bin.jar 2. package com.jmu.ccjoin.web.controller; import jav ...
- HDU1569 方格取数(2) —— 二分图点带权最大独立集、最小割最大流
题目链接:https://vjudge.net/problem/HDU-1569 方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- HDU 1081:To The Max
To The Max Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- YTU 2425: C语言习题 输出月份
2425: C语言习题 输出月份 时间限制: 1 Sec 内存限制: 128 MB 提交: 476 解决: 287 题目描述 编写一程序,输入月份号,输出该月的英文月名.例如,输入3,则输出Mar ...
- hdu 2544 最短路 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 题目意思:给出 n 个路口和 m 条路,每一条路需要 c 分钟走过.问从路口 1 到路口 n 需 ...
- 设置Tomcat的jvm内存问题
tomcat的jvm大小设置与操作系统以及jdk有关:具体来说: 1.操作系统是32bit的,程序最大内存访问空间是4G, 2的32次方,这是硬件决定的,跟windows linux没有任何关系. 2 ...
- 如何在cowboy应用中指定mnesia数据库路径
创建mnesia数据库的步骤简述: 1)定义脚本: -module(mns). -export([setup/0, clean/0]). -record(user, { id, coin, diamo ...
- Servlet的HelloWorld
设置好TOMCAT环境变量(如何设置?)后在命令行输入startup可以启动Tomcat,输入shutdown可以关闭Tomcat. /WEB-INF/web.xml是称为部署描述器的配置文件,Jav ...