Когда использовать throws в объявлении метода Java? - PullRequest
81 голосов
/ 09 декабря 2010

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

    public void method() throws SomeException
    {
         // method body here
    }

Из прочтения некоторых похожих постов я понял, что throws используется как своего рода объявление, которое SomeException может быть выдано во время выполнения метода.

Моя путаница возникает из-за кода, который выглядел так:

     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

Есть ли причина, по которой вы хотели бы использовать throws в этом примере? Кажется, что если вы просто выполняете базовую обработку исключений чего-то вроде IOException, вам просто понадобится блок try / catch, и все.

Ответы [ 7 ]

78 голосов
/ 09 декабря 2010

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

Как правило, если вы не собираетесь ничего делать с исключением, вам не следует его ловить.

Самое опасное, что вы можете сделать, это поймать исключение и ничего с ним не делать.

Хорошее обсуждение того, когда уместно создавать исключения, находится здесь

Когда выдается исключение?

21 голосов
/ 09 декабря 2010

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

Смотрите здесь некоторые сведения о проверенных и непроверенных исключениях: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Если метод перехватывает исключение и обрабатываетс ним внутри (как в вашем втором примере), тогда нет необходимости включать предложение throws.

9 голосов
/ 09 декабря 2010

Код, который вы посмотрели, не идеален.Вы должны либо:

  1. Поймать исключение и обработать его;в этом случае throws не требуется.

  2. Удалите try/catch;в этом случае исключение будет обработано вызывающим методом.

  3. Перехватите исключение, возможно, выполните какое-то действие и затем сбросьте исключение (не только сообщение)

2 голосов
/ 09 декабря 2010

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

1 голос
/ 30 ноября 2017

Это не ответ, а комментарий, но я не смог написать комментарий с отформатированным кодом, поэтому вот комментарий.

Допустим, есть

public static void main(String[] args) {
  try {
    // do nothing or throw a RuntimeException
    throw new RuntimeException("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

Выход

test
Exception in thread "main" java.lang.RuntimeException: test
    at MyClass.main(MyClass.java:10)

Этот метод не объявляет никаких исключений "throws", но генерирует их! Хитрость заключается в том, что выбрасываемые исключения - это RuntimeExceptions (непроверенные), которые не нужно объявлять в методе. Это немного вводит в заблуждение читателя метода, поскольку все, что она видит, - это «бросить е»; оператор, но нет объявления исключения бросков

Теперь, если у нас есть

public static void main(String[] args) throws Exception {
  try {
    throw new Exception("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

Мы ДОЛЖНЫ объявить исключения «throws» в методе, в противном случае мы получим ошибку компилятора.

1 голос
/ 19 октября 2012

Код, который вы опубликовали, неверен, он должен выдавать исключение, если перехватывает определенное исключение, чтобы обработать IOException, но выдает не отловленные исключения.

Что-то вроде:

public void method() throws Exception{
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println(e.getMessage());
   }
}

или

public void method(){
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println("Catching IOException");
           System.out.println(e.getMessage());
   }catch(Exception e){
           System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc.");
           System.out.println(e.getMessage());
   }

}

1 голос
/ 09 декабря 2010

В приведенном вами примере метод никогда не вызовет IOException, поэтому объявление является неправильным (но действительным).Я предполагаю, что оригинальный метод вызвал IOException, но затем он был обновлен для обработки исключения внутри, но объявление не было изменено.

...