我是Java初学者,并且知道try...catch
语句用于处理异常;表示try
块抛出异常时,执行catch
块。所以,我的问题是,当我尝试使用以下代码(没有try catch
)时,它会在IOException
方法中抛出未报告的read()
,但是当我使用try catch
时,它可以正常工作。
为什么在try
块中出现上述异常并且打印出exception occured
时控件是否转移到catch语句?
这是我的代码:
class Test00 {
public static void main(String args[]) {
char ch;
try {
ch=(char)System.in.read();//here exception is thrown without using try..catch
System.out.println(ch);
} catch(Exception e) {
System.out.print("exception occured");
}
}
}
我认为编译器会抛出一个异常,这就是代码与try catch一起工作的原因。但是为什么不执行catch块呢?我得错了。
答案 0 :(得分:8)
编译器告诉你可以被抛出,并且你必须满足这种可能性。
编译器正在对您的代码进行静态分析。它无法说明代码在实践中如何实际运行。
这可能令人沮丧。例如如果我写:
new URL("http://www.stackoverflow.com");
编译器会坚持我抓到MalformedURLException。很明显URL很好,但编译器警告我,因为我可以使用以下方法构造URL
对象:
new URL(potentiallyDubiousUserInput);
我不能保证字符串potentiallyDubiousUserInput
会是什么。
这些被称为已检查异常,您必须处理它们(捕获或声明它们被进一步抛出)。它们可能很痛苦,您会在Scala等语言中看到所有异常都是未选中。也就是说,您没有明确地处理它们。
有关详细信息,请参阅this question/answer。
答案 1 :(得分:1)
你必须在编译器告诉你的内容和运行时发生的事情之间区分(并清楚地告诉我们,以便我们不必解开它)。
在你的情况下,没有try-catch,编译器告诉你read()
可能抛出,并且你必须以某种方式处理异常。这就是你通过添加try-catch所做的。
然而,当你运行该程序时,它实际上没有抛出(一般来说,这个程序不太可能抛出),所以它从未进入catch块。
答案 2 :(得分:0)
这是因为System.in.read()
可以抛出IOException,这是一个已检查的异常。正如JLS 11.2.3中提到的关于已检查异常:
如果E是一个经过检查的异常类,并且E不是方法或构造函数的throws子句中声明的某个类的子类,则方法或构造函数体可以抛出一些异常类E,这是一个编译时错误。