我已经知道java中的传统Try块必须至少有catch块或者最后阻塞(两者或两者),并且我已经知道必须处理或声明已检查的异常。 但我想知道为什么它不会编译虽然我使用了正确的try块语法
我在这里有这段代码,在主要方法中我使用了Try with finally block但是我想知道为什么它不会编译
这是我的代码:
import java.io.IOException;
import java.net.Socket;
public class ExHandling {
public void connect() throws IOException
{
Socket s = new Socket();
try
{
s.getInputStream();
}
catch(IOException e )
{
e.printStackTrace();
}
finally
{
s.close();
}
}
public static void main(String []args)
{
ExHandling ex = new ExHandling();
try
{
ex.connect();
}
finally
{
System.out.println("Finally");
}
}
}
任何帮助请
答案 0 :(得分:2)
从throws
方法中删除connect()
子句。它已经捕获IOException
。如果您将方法声明为抛出已检查的异常,则必须在调用时捕获它。
更新:由于Socket#close()本身可以抛出异常,你需要决定你想做什么。异常处理很难,因为人们往往只考虑程序可以采取的最快乐的路径。
如果您不想在main()
方法中显式捕获异常,那么您只有一个选择:将调用包装到s.close()
(以及可以抛出已检查异常的所有其他方法)进入其自己的try-catch
块并删除throws
子句:
public void connect() {
Socket s = new Socket();
try {
s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但你应该想 - “当它失败时该怎么办?” - 每次你处理可能抛出的代码时。
答案 1 :(得分:0)
抓住抛出的IOException
或扔掉它,让JVM
处理它。
答案 2 :(得分:0)
IOException已检查异常,因此您需要 catch 或向签名方法添加例外。 最终只是保证最终块将被执行。
答案 3 :(得分:0)
声明您的main
方法以捕获IOException
。如果这样做,当您的connect()
方法中抛出异常时,它将传播到main
方法,并且您的finally块将被执行。如果那就是你想要的。
答案 4 :(得分:0)
最终本身无法处理任何异常。因此,当最终使用try {}时,try中的代码应该不会引发任何异常,或者您的方法必须抛出异常。
答案 5 :(得分:0)
它不会编译,因为正如您所指出的那样,finally块中的s.close()可以抛出IOException并且您选择通过指定“throws IOException”子句来处理该已检查的异常。由于这个选择,调用方法必须通过捕获它来处理该检查的异常,或者指定它将抛出异常。
目前还不清楚除了必须编译之外你想要什么结果,所以这里有三个选项:
1)用它自己的try / catch包裹s.close并删除throws子句。
2)在调用者的try / catch中移动“ExHandling ex”定义。
3)向调用者添加throws子句(如果需要,删除try / finally)。的推荐强>
注意:您真的不想捕获异常并执行“e.printStackTrace();”。所有这些都是你逻辑中的掩码问题。如果你计划以某种方式处理它,你应该只捕获一个例外;否则,您应该允许异常传播给调用者链。因此,只使用选项1& 2如果你真的想在所有的catch条款中做些什么。
选项1:使用自己的try / catch包装s.close并删除throws子句。
public void connect() {
Socket s = new Socket();
try {
s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExHandling ex = new ExHandling();
try {
ex.connect();
}
finally {
System.out.println("Finally");
}
}
选项2:在调用者的try / catch中移动“ExHandling ex”定义。 在这种情况下,我建议使用try with resources for socket。
public void connect() throws IOException {
Socket s = new Socket();
s.getInputStream();
s.close();
}
public static void main(String[] args) {
try {
ExHandling ex = new ExHandling();
ex.connect();
} catch (IOException e) {
e.printStackTrace();
}
finally {
System.out.println("Finally");
}
}
选项3:向调用者添加throws子句(如果需要,删除try / finally)。的推荐强>
public void connect() throws IOException {
Socket s = new Socket();
s.getInputStream();
s.close();
}
public static void main(String[] args) throws IOException {
ExHandling ex = new ExHandling();
ex.connect();
System.out.println("Finally");
}