Вопрос

Я могу «исправить» приведенное ниже исключение с помощью цикла try-catch, но не могу понять причину.

  1. Почему часть «in.readLine()» постоянно вызывает исключения IOExceptions?
  2. Какова на самом деле цель создания таких исключений, а не просто дополнительные побочные эффекты?

Код и IOExceptions

$ javac ReadLineTest.java 
ReadLineTest.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown
  while((s=in.readLine())!=null){
                      ^
1 error
$ cat ReadLineTest.java 
import java.io.*;
import java.util.*;

public class ReadLineTest {
 public static void main(String[] args) {
  String s;
  BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  // WHY IOException here?
  while((s=in.readLine())!=null){
   System.out.println(s);
  }
 }
}
Это было полезно?

Решение

Основная идея состоит в том, что буферные делегаты делегаты различным видам читателю, поэтому он проходит на это исключение.

Этот разный вид читателя может прочитать из какого-то волатильного внешнего ресурса, скажем, файловая система в случае fileheader. Файловая система чтения может потерпеть неудачу по многим причинам в любое время. (Ситуация хуже, если читатель получает свои основные данные из сетевого потока). Файл может быть удален из подвода (в зависимости от файловой системы и OS вовлеченности).

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

Другие советы

  1. Это не будет «постоянно зажечь» их, это просто мощь брось их каждый раз, когда вы ссылаетесь. В вашем случае, если он бросает то, что это означает, что что-то плохое не так с вашим стандартным входом.
  2. Цель состоит в том, чтобы вы, программист, используя API, имеет дело с проблемой, поскольку она в целом предполагается, что является возмещенной проблемой - хотя в вашем конкретном случае будет фатальна для всей вашей программы.

BufferedReader.readLine() объявляется как потенциально бросать исключение, см.: http://java.sun.com/j2se/1.3/docs/api/java/io/buffedreader.html#Readline ()

Вам либо нужно поймать его, либо объявить свой основной метод в качестве броска IOException.

Т.е. либо делаю это:

try {
    while((s=in.readLine()) != null){
        System.out.println(s);
     }
} catch(IOException e) {
    // Code to handle the exception.
}

Или

public static void main(String[] args) throws IOException { ...

IOException — это проверенное исключение.Вы должны либо поймать его, либо передать его вызывающему методу.Проверенные исключения вызваны внешними факторами, такими как отсутствующий файл, неисправный диск или что-то еще, что вы не можете восстановить в своем программном коде.

Однако исключение Unchecked, такое как ArrayIndexOutofBoundsException, вызвано ошибочной логикой в ​​программе.Вы можете изменить это, используя условие if вне вашего дефектного кода (что-то вроде if currIndex>array.length).В случае проверенного исключения такое положение не предусмотрено.

Это брошено, если исключительная ситуация возникает с помощью I / O, например источник потока больше не доступен.

В таких случаях ваша программа должна быть в состоянии восстановить. Либо путем перевода источника или с использованием некоторых по умолчанию или предупреждении пользователя о проблеме.

Вы вынуждены catch Это, потому что это проверенное исключение, и вы должны быть в состоянии оправиться от них.

Конечно, у вас есть возможность заявить, что текущий MENTED throws Это исключение в методах вызывающего абонента, но вам придется уловить его в конечном итоге (или позволить ему пузыриться до основного метода, когда он просто напечатан на консоли, и выполнение программы останавливается)

С использованием Scanner Для чтения файлов (или другого типа ввода) могут быть чрезвычайно неэффективными в середине / крупных ситуациях. Если у вас есть производительность, касающиеся чтения тысяч или миллионов строк, я настоятельно рекомендую вам использовать Буферреджер Вместо этого класса. Пример использования буферреджера для чтения строк от System.in отображается ниже:

public static void main(String[] args) throws Exception {

    String line = null;
    BufferedReader br = new BufferedReader (new InputStreamReader(System.in));

    try {
        /* This is protected code. If an problem occurs here, catch block is triggered */
        while ( (line = br.readLine()) != null ){
            System.out.println(line); 
        }
    }
    catch (IOException e){
        throw new IOException("Problem reading a line",e);
    }
}

IOException следует использовать в try/catch блок так может быть вызван всякий раз, когда защищенный код внутри try страдает от «исключительного» поведения, такого как ошибка. У Java есть свои исключения, которые выброшены, когда произойдет аналогичная ситуация. Например, ArrayIndexOutOfBoundsException выброшен, когда вы определяете массив a размер n и вы пытаетесь получить доступ к позиции a[n+1] Где-то в вашем коде. В виде ArrayIndexOutOfBoundsException, Есть много других классов исключения, которые вы можете бросить и настраивать свои собственные сообщения. Код, подходящий для исключения, должен быть помещен в защищенную зону в блоке попробовать. Когда исключение происходит в этом блоке, исключение будет обрабатываться в блоке Catch с ним.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top