首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >try语句之后的所有内容都必须包含在try语句中才能访问其中的变量吗?

try语句之后的所有内容都必须包含在try语句中才能访问其中的变量吗?
EN

Stack Overflow用户
提问于 2010-05-01 00:30:48
回答 7查看 301关注 0票数 7

我正在学习java,我发现有一件事是我不喜欢的,那就是当我有这样的代码时:

代码语言:javascript
运行
复制
import java.util.*;
import java.io.*;

public class GraphProblem
{
    public static void main(String[] args)
    {
        if (args.length < 2)
        {
            System.out.println("Error: Please specify a graph file!");
            return;
        }


        FileReader in = new FileReader(args[1]);
        Scanner input = new Scanner(in);

        int size = input.nextInt();
        WeightedGraph graph = new WeightedGraph(size);

        for(int i = 0; i < size; i++)
        {
            graph.setLabel(i,Character.toString((char)('A' + i)));
        }

        for(int i = 0; i < size; i++)
        {
            for(int j = 0; j < size; j++)
            {
                graph.addEdge(i, j, input.nextInt());
            }
        }

        // .. lots more code

    }
}

我的FileReader周围有一个未捕获的异常。

因此,我必须将其包装在try-catch中以捕获特定的异常。我的问题是,在我的方法中,如果想要使用我的FileReader ( in )或我的Scanner (input),try { }是否必须包含其后的所有内容?

如果我没有将整个程序的其余部分包装在try语句中,那么它之外的任何东西都不能访问in/input,因为它可能没有被初始化,或者已经被初始化到了它的作用域之外。因此,我不能将try-catch隔离为只说初始化FileReader的部分,并在那之后立即关闭try语句。

那么,“最佳实践”是不是让try语句包装所有要在其中访问变量的代码部分呢?

谢谢!

EN

回答 7

Stack Overflow用户

发布于 2010-05-01 00:35:08

如果您习惯于在FileReader构造函数之后使用而不是包装代码,则可以在try/catch块外部声明FileReader,如下所示:

代码语言:javascript
运行
复制
FileReader fr = null;
try
{
    fr = new FileReader(args[1]);
}
catch (IOException e)
{
    // handle
}
// code that uses fr

这是一个合理的设计,我经常使用它。在下面的代码中,确保正确处理fr为空的可能性(即构造函数抛出异常)。

票数 9
EN

Stack Overflow用户

发布于 2010-05-01 01:05:57

这对于try/catch块本身并不是问题。问题是变量作用域,并且由于检查到的异常,您必须具有try/catch块,从而建立新的作用域。

您还有另一个选择--从您的方法中将选中的异常声明为throws

代码语言:javascript
运行
复制
public static void main(String[] args) throws IOException {
    // ...code here...
}

对于main方法,这是完全合法的。

如果您确实想要处理异常,就像在一个较大的程序中应该做的那样。您可以围绕有问题的代码块定义特定的try/catch,并通过在该范围外声明变量来在该范围外使用该变量,正如许多人回答的那样:

代码语言:javascript
运行
复制
FileReader fr = null; // must be initialized here if the exception handling code 
                      // does not exit the method
try {
    fr = new FileReader(fileName);
} catch (IOException ex) {
    // log, print, and/or return
    // if you return or exit here then subsequent code can assume that fr is valid
}

您还可以将移动代码放到另一个处理异常的方法中:

代码语言:javascript
运行
复制
private static FileReader openReader(String fileName) {
    try {
        return new FileReader(fileName);
    } catch (IOException ex) {
        // log/print exception
        return null; // caller must then expect a null
        // or
        throw new RuntimeException(...); // throw a RuntimeException of some kind (may not be good practice either)
    }
}

您还可以将文件处理代码移动到另一种方法。这可能会更好,并让你更正确地遵循open/close in finally的习惯用法:

代码语言:javascript
运行
复制
FileReader fr = null;
try {
    fr = new FileReader(fileName);
    Scanner input = new Scanner(fr);

    processInput(input);
} catch (IOException ex) {
    // log/print exception
} finally {
    if (fr != null) {
        try {
            fr.close();
        } catch (IOException ex) {
            // empty
        }
    }
}

private static void processInput(Scanner in) throws IOException {
    // ...processing here
}

对于close部分,您可以使用第三方库(Apache File Utils)或编写一个简单的方法来提供不抛出异常的静态安全close方法。

您真的应该考虑将大型方法分解为较小的单元,这通常也会为您提供更清晰的异常处理方法。

票数 4
EN

Stack Overflow用户

发布于 2010-05-01 00:37:33

不是的。您可以这样声明它:

代码语言:javascript
运行
复制
FileReader in = null;
Scanner input = null;

try {
   in = new FileReader(args[1]);
   input = new Scanner(in);
} catch(IOException ioe) {
   //
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2746098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档