简体   繁体   English

Java异常处理方法

[英]Java exception handling method

I'm having a little bit of trouble implementing the following method while handling the 3 exceptions I'm supposed to take care of. 在处理我应该处理的3个异常时,在实现以下方法时遇到了一些麻烦。 Should I include the try/catch blocks like I'm doing or is that to be left for the application instead of the class design ? 我应该像我正在做的那样包括try / catch块,还是应该留给应用程序而不是类设计

The method says I'm supposed to implement this: 该方法说我应该实现这一点:

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

This method loads the info from the archive specified in a catalog of products and returns the catalog. 此方法从产品目录中指定的存档中加载信息,然后返回目录。

It starts by opening the file for reading. 首先打开文件进行读取。 Then it proceeds to read and process each line of the file. 然后,它继续读取和处理文件的每一行。

The method String.startsWith is used to determine the type of line: 方法String.startsWith用于确定线的类型:

  • If the type of line is "Product", the method readProduct is called. 如果行的类型是“产品”,则调用readProduct方法。
  • If the type of line is "Coffee", the method readCoffee is called. 如果行的类型是“ Coffee”,则调用readCoffee方法。
  • If the type of line is "Brewer", the method readCoffeeBrewer is called. 如果行的类型是“ Brewer”,则调用方法readCoffeeBrewer。

After the line is processed, loadCatalog adds the product (product, coffee or brewer) to the catalog of products. 在生产线处理之后, loadCatalog将产品(产品,咖啡或loadCatalog添加到产品目录中。

When all the lines of the file have been processed, loadCatalog returns the Catalog of products to the method that makes the call. 处理完文件的所有行后, loadCatalog将产品目录返回给进行调用的方法。

This method can throw the following exceptions: 此方法可以引发以下异常:

  • FileNotFoundException — if the files specified does not exist. FileNotFoundException如果指定的文件不存在。
  • IOException — If there is an error reading the info of the specified file. IOException —如果读取指定文件的信息时发生错误。
  • DataFormatException — if a line has errors(the exception must include the line that has the wrong data) DataFormatException如果一行有错误(异常必须包括数据错误的行)

Here is what I have so far: 这是我到目前为止的内容:

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;
}

It depends on whether you want the class or another portion of the application that is using it to handle the exception and do whatever is required. 这取决于您是要使用类还是使用它的应用程序的其他部分来处理异常并执行所需的任何操作。

Since the code that will use the loadCatalog() probably won't know what to do with a file I/O or format exception, personally, I'd go with creating an exception like CatalogLoadException and throw it from within the loadCatalog() method, and put the cause exception ( FileNotFoundException , IOException , DataFormatException ) inside it while including an informative message depending on which exception was triggered. 由于将使用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.
    }

This way your loadCatalog() method will only throw one single and meaningful exception. 这样,您的loadCatalog()方法将仅引发一个有意义的异常。

Now the code that will use loadCatalog() will only have to deal with one exception: CatalogLoadException . 现在,将使用loadCatalog()的代码只需处理一个异常: CatalogLoadException

loadCatalog(String filename) throws CatalogLoadException

This also allows your method to hide its implementation details so you do not have to change its "exception throwing" signature when the underlying low level structure changes. 这也使您的方法可以隐藏其实现细节,因此当基础底层结构发生更改时,您不必更改其“异常抛出”签名 Note that if you change this signature, every piece of code would need to change accordingly to deal with the new types of exceptions you have introduced. 请注意,如果更改此签名,则每段代码都需要进行相应更改,以处理您引入的新类型的异常。

See also this question on Exception Translation . 另请参阅有关异常翻译的问题。


Update on the throwing signature requirement: 关于投掷签名要求的更新:

If you have to keep that signature then you don't really have a choice but to throw them to the application and not catch them inside the loadCatalog() method, otherwise the throws signature would be sort of useless, since we aren't going to throw the exact same exception that we have just dealt with. 如果您必须保留该签名,那么您别无选择,只能throw它们throw应用程序中,而不是throw它们catchloadCatalog()方法中,否则, throws签名将是无用的,因为我们不会引发与我们刚刚处理的完全相同的异常。

The general idea is that you percolate exceptions up to the appropriate place to handle them. 通常的想法是,将异常渗透到适当的位置进行处理。 I am going to guess that your instructor expects them to be handled in main. 我猜想您的老师希望他们能得到主要处理。 In this case I can guess that because of the throws clause you were given. 在这种情况下,我可以猜到是由于throws子句而获得的。 A simple rule of thumb is that if the method declares the exception in the throws clause you do not catch it in that method. 一个简单的经验法则是,如果该方法在throws子句中声明了异常,则不会在该方法中捕获该异常。 So the method you are writing should have no catch statements. 因此,您正在编写的方法应该没有catch语句。

To do that you would change your code something like: 为此,您将更改代码,例如:

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;
}

and then in the method (presumably main) that calls loadCatalog you would have: 然后在调用loadCatalog的方法(大概是main)中,您将拥有:

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

replacing the printStackTrace with something appropriate. 用适当的东西替换printStackTrace。

That way the method, loadCatalog, doesn't deal with displaying the error messages, so you can call the method in GUI or console code and the code that calls it can choose how to display the error to the user (or deal with it in some way). 这样,方法loadCatalog不会处理显示错误消息,因此您可以在GUI或控制台代码中调用该方法,并且调用该方法的代码可以选择如何向用户显示错误(或在其中处理错误)。某种方式)。

Here is an excellent article of Heinz Kabutz, dealing with exception handling. 这是Heinz Kabutz出色的文章,涉及异常处理。

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

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

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