2013-04-20 2 views
1

Я читаю из файла, и я хочу обрабатывать исключения, используя блоки try/catch. Я написал свой код. Тем не менее, eclipse дал мне ошибку с просто объявлением моего объекта сканера, и мне пришлось инициализировать его до нуля. Ниже я написал две версии моего кода. Что считается лучшей практикой? Кроме того, лучше ли использовать блок try/catch, чем просто выбросить исключение в конце заголовка конструктора/функции?Java Scanner Good Practice

код версии # 1:

java.util.Scanner in = null; 

try { 
    in = new java.util.Scanner (f); 
    /* use scanner */ 
} catch (FileNotFoundException e) { 
    System.err.println("File was not found. Make sure the file exist."); 
    System.err.println("Message: " + e.getMessage()); 
} catch (IOException e) { 
    System.err.println("File could not be opened."); 
    System.err.println("Message: " + e.getMessage()); 
} finally { 
    in.close(); 
} 

код версии # 2:

try { 
    java.util.Scanner in = new java.util.Scanner (f); 
    /* use scanner */ 
    in.close(); 
} catch (FileNotFoundException e) { 
    System.err.println("File was not found. Make sure the file exist."); 
    System.err.println("Message: " + e.getMessage()); 
} catch (IOException e) { 
    System.err.println("File could not be opened."); 
    System.err.println("Message: " + e.getMessage()); 
} 
+1

Код версии №1: лучше. –

+0

Есть ли какая-то особая причина, или это просто то, что более распространено? –

ответ

1

В версии кода # 2, если будет сгенерировано исключение, прежде чем in.close(); файл обыкновение быть закрыты. Версия №1 не имеет этой проблемы.

Вы можете объединить эти две версии, используя попытку с ресурсом

try (java.util.Scanner in = new java.util.Scanner (new File("your file"))){ 
    /* use scanner */ 
} catch (FileNotFoundException e) { 
    System.err.println("File was not found. Make sure the file exist."); 
    System.err.println("Message: " + e.getMessage()); 
} catch (IOException e) { 
    System.err.println("File could not be opened."); 
    System.err.println("Message: " + e.getMessage()); 
} 
//"in" will be closed automatically 
+0

Я понимаю, что это особенность Java 7, однако я все еще использую Java 6 –

+1

В этом случае используйте версию # 1, так как она безопаснее версии №2. – Pshemo

4

Ни один из фрагментов не прав. Первый вызовет исключение NullPointerException, если конструктор Scanner генерирует исключение, потому что он не проверяет значение null перед вызовом функции close().

Второй не удается закрыть сканер в случае каких-либо исключений в блоке try.

Первый, очевидно, ближе к правильному коду, чем второй.

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

1

Ну, я думаю, что вторая версия кажется беспомощной. Если это исключение в блоке try, этот код не будет запущен.

in.close(); 

Почему бы не положить его в блок finally?

+0

В ver # 2 OP не сможет использовать ссылку 'in' в блоке finally, потому что он выходит за рамки. – Pshemo

+0

Вау, я думаю, мы можем поставить ссылку перед блоком try. – Luciens

+0

Затем вы получите версию №1. В этом и заключается основное различие между ними. – Pshemo

2

Java 7 представила «Попробовать с ресурсами», чтобы предотвратить утечку памяти из-за ресурсов, оставленных открытыми в таких случаях, как версия кода № 2, бонус: она проста в использовании.

try(Scanner in = new Scanner(System.in)) { 

    } 

И сделано. Вышеуказанное автоматически закроет сканер после брекетов, независимо от того, что происходит внутри брекетов.

Блокировка и окончание могут появляться вместе с Try with Resources, как обычно, но не обязательно.

+0

Это хорошее решение, однако я все еще использую Java 6 –

+1

Тогда версия 1 с 'finally {if (in! = Null) in.close(); } '- ваш лучший вариант. –