Метод обработки исключений Java - PullRequest
5 голосов
/ 04 июля 2010

У меня возникли небольшие проблемы с реализацией следующего метода при обработке трех исключений, о которых я должен позаботиться. Должен ли я включать блоки try / catch, как я делаю, или это нужно оставить для приложения вместо дизайна класса ?

Метод говорит, что я должен реализовать это:

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

Этот метод загружает информацию из архива, указанного в каталоге товаров, и возвращает каталог.

Он начинается с открытия файла для чтения. Затем он начинает читать и обрабатывать каждую строку файла.

Метод String.startsWith используется для определения типа линии:

  • Если тип строки - «Продукт», вызывается метод readProduct.
  • Если тип строки - «Кофе», вызывается метод readCoffee.
  • Если тип линии "Brewer", вызывается метод readCoffeeBrewer.

После обработки линии 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;
}

Ответы [ 3 ]

4 голосов
/ 04 июля 2010

Это зависит от того, хотите ли вы, чтобы класс или другая часть приложения, использующего его, обрабатывали исключение и делали все, что требуется.

Поскольку в коде будет использоваться loadCatalog() вероятно, не будет знать, что делать с файловым вводом-выводом или исключением формата, лично я бы пошел с созданием исключения, подобного CatalogLoadException, и бросил бы его из метода loadCatalog (), и поместил бы вызывает исключение (FileNotFoundException, IOException, DataFormatException) внутри него, включая информационное сообщение в зависимости от того, какое исключение было вызвано.

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 их в приложение, а не catch их в методе loadCatalog(), в противном случае подпись throws будет бесполезной, поскольку мы не собираемся бросать то же исключение, которое мы только что рассмотрелис.

1 голос
/ 05 июля 2010

Общая идея заключается в том, что вы предоставляете исключения вплоть до подходящего места для их обработки.Я предполагаю, что ваш инструктор ожидает, что они будут обработаны в основном.В этом случае я могу догадаться, что из-за условия бросков вам дали.Простое практическое правило заключается в том, что если метод объявляет исключение в предложении 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, у вас будет:

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

замена printStackTrace чем-то подходящим.

Таким образом, метод loadCatalog не работает с отображением сообщений об ошибках, поэтому вы можете вызвать метод в графическом интерфейсе или в консольном коде, а код, который вызывает его, выбрать.как отобразить ошибку пользователю (или как-то с ней справиться).

0 голосов
/ 06 июля 2010

Отличная статья Хайнца Кабуца, посвященная обработке исключений.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...