Что именно происходит, когда я сам выкидываю исключение со строкой параметра?Когда вызывается метод toString? - PullRequest
0 голосов
/ 27 октября 2018

Мне действительно трудно понять, как работает обработка исключений.Почему предпочтительнее расширить класс Exception вместо Throwable для моих собственных определенных пользователем исключений?

try {
   //some SQL exception
} 
catch(SQLException e) {
  System.out.println(e);
} 

Что на самом деле представляет e здесь?Я знаю, что это ссылка на объект исключения SQL, но что он будет печатать?Вызывает ли он метод toString?

Edit: вывод, который я получаю, сильно отличается, когда я переопределяю метод toString и когда я полностью удаляю его из моего исходного кода.Пожалуйста, объясните почему?

class MyException extends Throwable {
  private int detail;

  MyException(String msg) {
    super(msg);
  }

  public String toString() {
    return "MyException[" + detail + "]";
  } 
}

class ExceptionDemo {
  static void compute(int a) throws MyException {  // cant be thrown as throwable 
    System.out.println("Called compute(" + a + ")");
    if(a > 10)
      throw new MyException("MyException class error");
    System.out.println("Normal exit");
  }

  public static void main(String args[]) {
    try {
      compute(1);
      compute(20);
    } catch (MyException e) {
      System.out.println("Caught " + e);
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

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

Таким образом, вы не должны создавать свои собственные исключения, реализующие Throwable, и вы не должны перехватывать Throwable, потому что при этом вы также перехватываете тип ошибки, и ошибка не должна кэшироваться.

Стоит также упомянуть, что существует известный подтип Exception: RuntimeException. RuntimeException - это непроверенные исключения, то есть вы можете выбросить их, и вызывающая сторона не должна их перехватывать.

В течение многих лет велись большие споры об использовании Exception и RuntimeException. RuntimeException победил (некоторые, возможно, все еще думают об обратном, конечно), но в первые дни использование Exception считалось королем, поэтому несколько API-интерфейсов Java первых версий генерируют тип Exception, а современные Java-API и фреймворки большую часть времени генерируют RuntnimeException.

Что касается

Что на самом деле представляет здесь e? Я знаю, что это ссылка на объект исключения SQL, но что он будет печатать? Вызывает ли он метод toString?

Вы правы, e - это имя переменной типа SQLException, с которой вы можете работать внутри блока catch. И он вызывает свой метод toString, как каждый объект при добавлении в System.out.println ().

Редактировать: вывод, который я получаю, сильно отличается, когда я переопределяю метод toString и полностью удаляю его из моего исходного кода. Пожалуйста, объясните, почему?

В вашем примере вы расширяете Throwable, как уже упоминалось ранее, вы не должны этого делать. Все классы, расширяющие Throwable, будут использовать его реализацию toString (), в документации сказано:

/ ** * Возвращает краткое описание этого броска. * Результатом является объединение: *

  • {@linkplain Class # getName () name} класса этого объекта *
  • ":" (двоеточие и пробел) *
  • результат вызова этого объекта {@link #getLocalizedMessage} * метод *
* Если {@code getLocalizedMessage} возвращает {@code null}, тогда просто * имя класса возвращается. * * @ возвращаем строковое представление этого броска. * / public String toString ()

Итак, если вы переопределите это, как в вашем примере. Вы больше не получаете его преимуществ, ваш метод toString () печатает только то, что вы в него вставили.

0 голосов
/ 27 октября 2018

> Почему предпочтительнее расширять throwable вместо класса Exception для моих собственных определенных пользователем исключений?

Это не так. Вы отредактировали вопрос, чтобы изменить его на:

Почему предпочтительнее расширить Исключение вместо класса Throwable для моих собственных определенных пользователем исключений?

Потому что в общем случае исключения должны быть Exceptions; ключ в названии. :-) Throwable не исключение, это бросаемое. (Тем не менее, иерархия Throwable / Error / Exception / RuntimeException в JDK обычно рассматривается как плохо размеченная. Например, странно, что проверены Throwable и его подклассы, а также его подкласс Exception проверено, но его подкласса RuntimeException нет, и есть другой Throwable подкласс Error, который также не проверен. Я полагаю, что так происходит по историческим причинам, а не потому, что это отличный дизайн.)

Для ваших собственных исключений:

  • Расширьте Exception (или один из его подклассов, кроме RuntimeException), если ваше исключение должно быть проверено .

  • Расширьте RuntimeException (или один из его подклассов), если ваше исключение должно быть не проверено .

  • В очень маловероятном случае, когда вы пишете код, который соответствует определению Error, вы можете создать подкласс этого или одного из его подклассов, но я не думаю, что я когда-либо видел кодовую базу с Error подклассом. В основном, Error для ошибок уровня JVM, таких как «недостаточно памяти».

try { //some SQL exception} 
catch(SQLException e) {System.out.println(e);} 

Что на самом деле здесь представляет? Я знаю, что это ссылка на объект исключения SQL ...

Да, это экземпляр SQLException или его подкласс.

... но что это будет печатать? Вызывает ли он метод toString?

Да, косвенно: PrintStream#println(Object) вызывает String.valueOf(Object), что вызывает toString для объекта.

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

Поскольку ваш toString реализован не так, как реализован Throwable toString. Кроме того, вы делаете println, отличное от того, которое вы изначально показывали (с использованием конкатенации строк), хотя это не имеет большого значения. Ваш экземпляр toString используется независимо.

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