繁体   English   中英

Java异常处理方法

[英]Java exception handling method

在处理我应该处理的3个异常时,在实现以下方法时遇到了一些麻烦。 我应该像我正在做的那样包括try / catch块,还是应该留给应用程序而不是类设计

该方法说我应该实现这一点:

public Catalog loadCatalog(String filename)
         throws FileNotFoundException, IOException, DataFormatException

此方法从产品目录中指定的存档中加载信息,然后返回目录。

首先打开文件进行读取。 然后,它继续读取和处理文件的每一行。

方法String.startsWith用于确定线的类型:

  • 如果行的类型是“产品”,则调用readProduct方法。
  • 如果行的类型是“ Coffee”,则调用readCoffee方法。
  • 如果行的类型是“ Brewer”,则调用方法readCoffeeBrewer。

在生产线处理之后, loadCatalog将产品(产品,咖啡或loadCatalog添加到产品目录中。

处理完文件的所有行后, loadCatalog将产品目录返回给进行调用的方法。

此方法可以引发以下异常:

  • FileNotFoundException如果指定的文件不存在。
  • IOException —如果读取指定文件的信息时发生错误。
  • DataFormatException如果一行有错误(异常必须包括数据错误的行)

这是我到目前为止的内容:

public Catalog loadCatalog(String filename)
       throws FileNotFoundException, IOException, DataFormatException{
    String line = "";
    try {
        BufferedReader stdIn = new BufferedReader(new FileReader("catalog.dat"));
            try {
                BufferedReader input = new BufferedReader(
                    new FileReader(stdIn.readLine()));
                while(! stdIn.ready()){
                    line = input.readLine();                        
                    if(line.startsWith("Product")){
                        try {
                            readProduct(line);
                        } catch(DataFormatException d){
                            d.getMessage();
                        }
                    } else if(line.startsWith("Coffee")){
                        try {
                            readCoffee(line);                               
                        } catch(DataFormatException d){
                            d.getMessage();
                        }
                    }  else if(line.startsWith("Brewer")){
                        try {
                            readCoffeeBrewer(line);
                        } catch(DataFormatException d){
                            d.getMessage();
                        }
                    }
                }
            } catch (IOException io){
                io.getMessage();
            }
    }catch (FileNotFoundException f) {
        System.out.println(f.getMessage());
    }
    return null;
}

这取决于您是要使用类还是使用它的应用程序的其他部分来处理异常并执行所需的任何操作。

由于将使用loadCatalog()的代码可能不知道如何处理文件I / O或格式异常,因此就我个人而言,我将创建一个类似CatalogLoadException的异常并从loadCatalog()方法中抛出该异常,然后将原因异常FileNotFoundExceptionIOExceptionDataFormatException )放入其中,同时包含一条信息性消息,具体取决于触发了哪个异常。

try {
         ...
    //do this for exceptions you are interested in.
    } catch(Exception e) {
         //maybe do some clean-up here.
         throw new CatalogLoadException(e); // e is the cause.
    }

这样,您的loadCatalog()方法将仅引发一个有意义的异常。

现在,将使用loadCatalog()的代码只需处理一个异常: CatalogLoadException

loadCatalog(String filename) throws CatalogLoadException

这也使您的方法可以隐藏其实现细节,因此当基础底层结构发生更改时,您不必更改其“异常抛出”签名 请注意,如果更改此签名,则每段代码都需要进行相应更改,以处理您引入的新类型的异常。

另请参阅有关异常翻译的问题。


关于投掷签名要求的更新:

如果您必须保留该签名,那么您别无选择,只能throw它们throw应用程序中,而不是throw它们catchloadCatalog()方法中,否则, throws签名将是无用的,因为我们不会引发与我们刚刚处理的完全相同的异常。

通常的想法是,将异常渗透到适当的位置进行处理。 我猜想您的老师希望他们能得到主要处理。 在这种情况下,我可以猜到是由于throws子句而获得的。 一个简单的经验法则是,如果该方法在throws子句中声明了异常,则不会在该方法中捕获该异常。 因此,您正在编写的方法应该没有catch语句。

为此,您将更改代码,例如:

public Catalog loadCatalog(String filename) 
    throws FileNotFoundException, 
           IOException, 
           DataFormatException
{
    String line = "";

    BufferedReader stdIn = new BufferedReader(new FileReader("catalog.dat"));
    BufferedReader input = new BufferedReader(new FileReader(stdIn.readLine()));

    while(!stdIn.ready())
    {
        line = input.readLine();

        if(line.startsWith("Product"))
        {
            readProduct(line);
        } 
        else if(line.startsWith("Coffee"))
        {
            readCoffee(line);
        }  
        else if(line.startsWith("Brewer"))
        {
            readCoffeeBrewer(line);
        }
    }

    return null;
}

然后在调用loadCatalog的方法(大概是main)中,您将拥有:

try
{
   loadCatalog(...);
}
catch(FileNotFoundException ex)
{
    ex.printStackTrace(); 
}
catch(IOException ex)
{
    ex.printStackTrace(); 
}
catch(DataFormatException ex)
{
    ex.printStackTrace(); 
}

用适当的东西替换printStackTrace。

这样,方法loadCatalog不会处理显示错误消息,因此您可以在GUI或控制台代码中调用该方法,并且调用该方法的代码可以选择如何向用户显示错误(或在其中处理错误)。某种方式)。

这是Heinz Kabutz出色的文章,涉及异常处理。

http://www.javaspecialists.eu/archive/Issue162.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM