обработка исключений Java в конструкторе - PullRequest
2 голосов
/ 16 мая 2011

честно говоря, я не очень опытен в обработке исключений, потому что часто из-за своей лени я склонен не обрабатывать исключения.Итак, вот очень простой вопрос.

Я хотел бы знать, каков самый чистый способ решения этой ситуации с подходом обработки исключений:

У меня есть класс (ConfigManager), который читает файлв своем конструкторе, и нужно, чтобы этот файл существовал, чтобы быть правильно сконструированным, заданным в качестве параметра конструктора.Если файл не существует, я хотел бы перехватить исключение FileNotFoundException, создать файл с некоторыми значениями по умолчанию и продолжить создание объекта ConfigManager с доступным сейчас файлом конфигурации по умолчанию.

Вот некоторый код:

class ConfigManager{
    ConfigManager(String file){
         try{
             builder = builderFactory.newDocumentBuilder();
             document = builder.parse (new FileInputStream(file));
             ....
         }catch (FileNotFoundException e) {

        File configFile =  new File (file);

        try {

            configFile.createNewFile();
            BufferedWriter writer = new BufferedWriter(new FileWriter(configFile));
            writer.write(this.defaultConfig);
            writer.close();


            return new ConfigManager(string); //Here's the problem. I can't do that but I need to try build ConfigManager again. How do that?

        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}  

Как создать новый объект ConfigManager после создания файла конфигурации по умолчанию?Это самый правильный способ обработки такого типа исключений?

заранее спасибо

Ответы [ 8 ]

4 голосов
/ 16 мая 2011

Что вы можете сделать, это убедиться, что файл существует, прежде чем пытаться его проанализировать.

FileInputStream fis = null;
try {
    fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
    BufferedWriter writer = new BufferedWriter(new FileWriter(configFile));
    writer.write(defaultConfig);
    writer.close();
    fis = new FileInputStream(file);
}

try{
     builder = builderFactory.newDocumentBuilder();
     document = builder.parse (fis);
2 голосов
/ 16 мая 2011

не выполняйте чтение файла в конструкторе, создайте метод (возможно закрытый), который выполняет чтение файла и установку значений в ConfigManager.

Затем в конструкторе, где вы пытаетесь снова вызвать конструктор, просто вызовите метод.

т.е. не вызывайте конструктор снова.

обновление - я бы организовал код следующим образом:

ConfigManager(String fileName) {
   File file = new File(fileName);
   if (!file.exists()){
       // create this method -- Im assuming its ok to put the default 
       // config on the path where the file did not exist.
       createDefaultConfigFile(fileName); 
   }

   parseConfigFile(fileName, ...); // create this method too
}

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

1 голос
/ 17 мая 2011

часто из-за своей лени я склонен не обрабатывать исключения

Я предлагаю вам сначала исправить лень. На самом деле вы просто создаете больше работы для себя в дальнейшем.

1 голос
/ 16 мая 2011

Ну, на самом деле у вас есть новый экземпляр ConfigManager после того, как конструктор был выполнен без ошибки.Таким образом, все, что вам нужно сделать, это просто удалить строку, о которой идет речь.Это будет проверять файл только один раз, когда ваше приложение будет развернуто / запущено.

1 голос
/ 16 мая 2011

Попробуйте делегировать разбор файла конфигурации другому методу. Таким образом, вы можете проверить, существует ли файл сначала, а затем либо создать файл по умолчанию, либо передать существующий этому новому методу.

1 голос
/ 16 мая 2011

Самый простой способ сделать это - не выполнять никаких операций, которые могут привести к исключениям в конструкторе. Если вам абсолютно необходимо выполнить их, прежде чем ваш объект можно будет использовать, выполните их в отдельном методе init ().

1 голос
/ 16 мая 2011

Вам необходимо снова вызывать конструктор, но без создания нового объекта - просто вызывая его для того же объекта.Поскольку Java не позволяет вам этого делать, вы должны создать вспомогательный метод, переместить код из конструктора в него и затем вызвать новый метод из конструктора.

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

1 голос
/ 16 мая 2011

Решение состоит в том, чтобы разделить ваш конструктор на две части.Первая часть пытается создать FileInputStream из существующего файла.Если выдается FileNotFoundException, то вы создаете и заполняете файл, как указано выше, а затем снова открываете FileInputStream.Вторая часть берет файл FileInputStream, открытый первой частью (независимо от того, как он был открыт) и продолжает инициализацию.

Другой вариант - отложить эту загрузку до метода init(), чтобы потребителивашего класса должны как создавать, так и инициализировать свои объекты.

...