【问题标题】:Return in a 'finally' statement在“finally”语句中返回
【发布时间】:2013-01-03 21:43:46
【问题描述】:

我正在尝试从文件中读取 ObjectOutputStream 并将其转换为数组列表。 整个事情发生在一个应该读取文件并返回数组列表的方法中:

public static List<Building> readFromDatabase(){
    String fileName="database.txt";
    FileInputStream fileIStream=null;
    ObjectInputStream in=null;
    List<Building> buildingsArr=null;
    try
     {
        fileIStream = new FileInputStream(fileName);
        in = new ObjectInputStream(fileIStream);
        buildingsArr=(ArrayList<Building>)in.readObject();
     }
     catch(IOException e)
     {
        e.printStackTrace();
     }
     catch(ClassNotFoundException e)
     {
        Console.printPrompt("ArrayList<Building> class not found.");
        e.printStackTrace();
     }
    finally{
        Console.printPrompt("Closing file...");
        close(in);
        close(fileIStream);
        return buildingsArr;
    }
}

Java 告诉我这很危险。 有哪些替代方案? 我不能将 return 放在“try”块中,因为它不会这样做/它不会关闭“finally”块中的文件。 我需要确保文件将被关闭,并返回我创建的数组列表。 有什么想法吗?

【问题讨论】:

  • 为什么不把return 语句放在finally 块之后?
  • close(fileIStream); 可以(实际上应该)被忽略,因为in.close() 会关闭它。
  • 附带说明,这是很危险的,因为有可能发生这样的事情:try { return true; } finally { return false; }
  • 并且关闭(fileOStream) 可以吗?

标签: java file stream


【解决方案1】:

我不能将 return 放在“try”块中,因为它不会这样做/它 不会关闭“finally”块中的文件。

错了,如果你把 return 放在 try 块中,finally 块仍然会执行。因此,您可以在 try 块中返回。

try
     {
        //your code
        return buildingsArr;
     }
     catch(IOException e)
     {
        e.printStackTrace();
     }
     catch(ClassNotFoundException e)
     {
        Console.printPrompt("ArrayList<Building> class not found.");
        e.printStackTrace();
     }
    finally{
        Console.printPrompt("Closing file...");
        close(in);
        close(fileIStream);
    }

【讨论】:

  • 我既需要回归,也需要最终实现。在 finally 子句之前返回还会发生吗?如果是,问题解决了
  • 两者都会发生。 finally 会在 return 语句之前执行。
  • 如果你不抛出 Exception 或者在 finally 之后返回一些东西,这甚至不会编译! 因为这不是一个正确的答案!
【解决方案2】:

我建议开始使用 Java 7,以及 try with resources 子句。 http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

例如:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

【讨论】:

    【解决方案3】:

    您必须抛出异常或返回值:

    您需要证明这一点的只是注释掉 finally 块后的 return "File Not Found" 并查看它不会编译。

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    
    public class ReturnFinallyExample
    {
        public static void main(final String[] args)
        {
            returnFinally();
        }
    
        private static String returnFinally()
        {
            try
            {
                final File f = new File("that_does_not_exist!");
                final FileInputStream fis = new FileInputStream(f);
                return "File Found!";
            }
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
            finally
            {
                System.out.println("finally!");
            }
            return "File Not Found!";
        }
    }
    

    return 必须在 finally 之后,或者您必须:

    将方法声明为throws FileNotFoundExceptoin并重新抛出FileNotException

    throw new RuntimeException(e) 包裹FileNotFoundException

    【讨论】:

      猜你喜欢
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 2011-11-04
      • 2020-02-12
      • 1970-01-01
      • 2018-04-18
      相关资源
      最近更新 更多