3. Опаковане на изключения

Проверените изключения изглеждаха готини на теория, но се оказаха огромно разочарование на практика.

Да предположим, че имате супер популярен метод във вашия проект. Извиква се от стотици места във вашата програма. И вие решавате да добавите ново отметнато изключение към него. И може би това проверено изключение е наистина важно и толкова специално, че само main()методът знае Howво да прави, ако бъде хванат.

Това означава, че ще трябва да добавите провереното изключение към throwsклаузата на всеки метод, който извиква вашия супер популярен метод . Както и в throwsклаузата на всички методи, които извикват тези методи. И на методите, които извикват тези методи.

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

И тогава целият ви code (всички промени в стотици файлове) ще трябва да бъде прегледан от други програмисти. И в този момент се питаме защо направихме толкова много кървави промени в проекта? Ден(и?) работа и повредени тестове – всичко това в името на добавянето на едно проверено изключение?

И разбира се, все още има проблеми, свързани с наследяването и преодоляването на метода. Проблемите, които идват от проверените изключения, са много по-големи от ползата. Изводът е, че сега малко хора ги обичат и малко хора ги използват.

Все още обаче има много code (включително standardн code на Java библиотека), който съдържа тези проверени изключения. Какво да се прави с тях? Не можем да ги пренебрегнем и не знаем How да се справим с тях.

Програмистите на Java предложиха да обгърнат проверените изключения в RuntimeException. С други думи, уловете всички проверени изключения и след това създайте непроверени изключения (например RuntimeException) и ги изхвърлете instead of това. Пequalsето на това изглежда нещо подобно:

try
{
   // Code where a checked exception might occur
}
catch(Exception exp)
{
   throw new RuntimeException(exp);
}

Това не е много красиво решение, но тук няма нищо престъпно: изключението беше просто напъхано в RuntimeException.

Ако желаете, можете лесно да го извлечете от там. Пример:

Код Забележка
try
{
   // Code where we wrap the checked exception
   // in a RuntimeException
}
catch(RuntimeException e)
{
   Throwable cause = e.getCause();
   if (cause instanceof Exception)
   {
      Exception exp = (Exception) cause;
      // Exception handling code goes here
   }
}







Вземете изключението, съхранено вътре в RuntimeExceptionобекта. Променливата causeможе би null

Определете нейния тип и я преобразувайте в проверен тип изключение.