class MyException extends Exception{
public MyException (String str){
super(str);
}
}
public class Test {
static public void shout(int i) throws MyException{
if(i==0) throw new MyException("first");
}
public static void main(String[] args) {
System.out.println("in main "+call());
}
public static int call() {
int i = 100;
try{
System.out.println("before try");
shout(0);
System.out.println("after try!");
return i*5;
}
catch(RuntimeException e){
e.printStackTrace();
i*=2;
return i*10;
}
finally{
i++;
System.out.println("finally block, i is : "+i);
return i*3;
}
}
}
上列代码中, 26 行的 shout(0)抛出的 MyException 没有被捕捉,按理来说应该编译不通过 但是能通过编译 但是如果我把 38 行的 return i*3;注释掉,就编译不过了 怎么回事?
1
Sharuru 2017-04-19 08:05:48 +08:00 via Android 1
通俗点讲,你 catch 的是 Runtime Exception ,改成 Exception 或者 MyException 被你的异常捕获。
Finally 表示必执行的部分,既然 return int ,那么作为“最后保险” 必然需要 return ,异常发生时, try 内的 return 已经不会去执行,直接执行 catch 操作,若非 catch 对象则 finally 。 |
2
momocraft 2017-04-19 08:42:35 +08:00 1
我觉得 finally 中有 return 时能编译是正常的: 有异常又在 finally 中 return 时异常会被吞掉,不会向上传递
编译错误描述的是: 删去 `return i*3` 后 MyException 可能向上传递,但 call 又不 throws MyException 这个不一致 只要 finally 中"可能"不 return , javac 就会认为异常"可能"不被吞掉,并强制你 throws 。比如把 return i*3 改成 if (XX) return i*3; 会得到同样的编译错误。 |
3
sorra 2017-04-19 09:44:45 +08:00
竟然有这种事!虽然能解释,但语言设计上给人不合理的感觉。
|
4
h3nng 2017-04-19 10:15:06 +08:00
#1 楼基本解释清楚了,补充一句吧:为什么你自定义的 Exception 没捕获也能通过编译?因为你在 finally 里有 return 值,也就是说无论如何你的 call()这个方法,最终都是有返回值的,因此能通过编译;你没捕获只能认为你忽略了此异常(所以一般不建议在 finally 里 return ,这样异常就被忽略掉了)。
|
8
yeyuexia 2017-04-19 13:41:30 +08:00
@sorra 你这个贴的问题明明白白是文档没读好的原因 甚至只要是看过一门带异常捕获的语言都会有解释的,然后就甩锅说语言设计不合理 那我只能理解你是新人零基础学编程了,建议多读读文档没什么问题吧?还有,没事干就让人亮岁数级别,现在这社会,是不是没宝马都没法教育人了 摊手
|
9
sorra 2017-04-19 14:10:31 +08:00
@yeyuexia 是你喊人年轻人,我就请你亮岁数级别嘛。现在你还居高临下说“教育人”
至于这个问题我是不同意你的意见的,我写 Java 也 5 年了, checked exception 本来就是有争议的,不要拿文档压人。你能从官方文档找出说明算我输。 |
10
yeyuexia 2017-04-19 15:13:03 +08:00
@sorra
catch 的用法 https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html RuntimeException https://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html finally https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html 函数定义 https://docs.oracle.com/javase/tutorial/java/javaOO/returnvalue.html 顺便请教下 checked exception 本来就是有争议的 这句从何而来? 我还真是无聊啊 2333 五年的 JAVA …… 敢问阁下从哪高就呢? |
11
sorra 2017-04-19 15:33:16 +08:00
@yeyuexia 你真的看了内容?哪里写了 return in finally block 的情况?哪里能教人避开楼主遇到的坑?
我告诉你我连语言规范都查了。 |
12
yeyuexia 2017-04-19 15:46:02 +08:00
专门给你贴了 return value 的连接 谢谢:)
|
13
sorra 2017-04-19 16:04:11 +08:00
@yeyuexia 原以为阁下有何高论,已全文阅读 return value 的链接,现在请你正面回答问题了。
附赠语言规范的链接 https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2 |
14
Sharuru 2017-04-19 16:23:42 +08:00
早上上班路上等地铁时候无聊回答的问题,结果变成了撕逼 233 。
|
15
yeyuexia 2017-04-19 16:27:44 +08:00
@sorra 于是你想说什么呢? 这就是你函数不返回值的原因?还是你觉得 java 应该用 catch RuntimeException 来捕获 MyException ?
看完文档了还好意思在这继续扯 那我也没什么跟你扯淡的必要了。啧啧 java 五年 |
16
sorra 2017-04-19 16:29:18 +08:00
@yeyuexia 语言规范有一行文字能稍微支持你,加油找,找到了让你赢一半行不行?既然你继续装逼,我只能继续质疑你有没有阅读文档的能力了
|
17
yeyuexia 2017-04-19 16:33:43 +08:00
@sorra 哎呦喂 不写定义函数 return type 是 int 然后不写 return 编译不过去质疑 java 有问题,程序抛出了自己没有捕获异常是 java 有问题 您继续……我错了 我居然在五年 java 经验的大牛这质疑真是我的不是 233
请去翻翻书看看编译的时候在干什么好么 ? (认真脸) |
18
sorra 2017-04-19 16:47:59 +08:00
我回复楼主的帖子,某个人来批判一番,口口声声叫人“先学会看文档”,自己恐怕根本没看过,一直不敢指出所谓的“文档”是哪一行文字。
现在揭晓答案吧:语言规范 https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2 那行粗体文字 为什么说不合理呢?因为大部分人都不知道有这么危险的行为:在 finally 中 return ,不但会扰乱返回值,还会导致 checked exception 越过检查, javac 的编译是没有警告的,只有 IDE 给出了普通警告。官方教程没写,只有语言规范在一个小节提了一下,而且措辞比较绕。 |