Try-Catch-Finally Block

时间:2017-11-15 14:22:43

标签: java exception-handling

我已经知道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");
        }

    }
}

任何帮助请

6 个答案:

答案 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");
    }