2013-12-05 3 views
2

Итак, мое обычное исключение - PatternFormatException, и я добавил throws PatternFormatException, до конца моего метода, но мне интересно, как я могу на самом деле заставить метод физически бросить его? Использую ли я if statements? то естьКак я могу получить метод для создания настраиваемого исключения, которое я создал?

if //[doesn't_parse] throw PatternFormatException 

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

+0

Да, вы можете. Просто сделай это и посмотри. –

ответ

5

Вы сгенерирует исключение, используя ключевое слово throw:

throw new PatternFormatException(...);

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

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

try { 
    doSomething(); // throws SomeException 
    doSomethingElse(); // throws SomeOtherException 
} 
catch (Exception e) { 
    throw new PatternFormatException(..., e); 
} 

вообще хорошо, если вы точно знаете, что исключения могут произойти, и если все они должным образом инкапсулируется PatternFormatException. Однако ключевая идея Exceptions в Java заключается в том, что вы всегда знаете обо всех возможных исключениях, которые могут произойти. Вот почему Java заставляет вас добавить все возможные исключения (за исключением RuntimeException) в объявление метода.

Более безопасный дизайн будет:

try { 
    doSomething(); // throws SomeException 
    doSomethingElse(); // throws SomeOtherException 
} 
catch (SomeException e) { 
    throw new PatternFormatException(..., e); 
} 
catch (SomeOtherException e2) { 
    throw new PatternFormatException(..., e2); 
} 
catch (Exception e3) { 
    throw new UnexpectedPatternFormatException(..., e3); 
} 

Обратите внимание, что первые два catch эсов называют различные конструктор, и, таким образом, может обрабатывать различные исключения по-разному. Последнее catch обертывает непредвиденное исключение, потому что ваша программа столкнулась с исключением (вероятно, RuntimeException), которого вы не планировали. Если пользователи затем жалуются на UnexpectedPatternFormatException, вы можете просто вернуться к своему коду и исправить код, чтобы исходное исключение либо больше не было брошено, либо обернуто более значимым образом. Вы также можете просто использовать один класс UnexpectedMySomethingException в качестве спада для всех блоков try/catch, которые у вас есть, чтобы сделать вещи немного проще.

Следует упомянуть последнее слово о проблемах, вызванных исключениями. Несмотря на то, что Java использует исключения для всех ситуаций, даже те, которые в значительной степени не находятся под контролем Java-программиста (например, при доступе к файлам или даже при попытке анализируем строки как числа), всегда помните, что броски и ловушки Исключения на самом деле довольно дороги, поэтому многие люди избегают этого. Только действительно используйте Исключения, если производительность не является проблемой (когда исключение является редким событием).

Кроме того, Исключения могут угрожать целостности состояния вашей программы, если вы выбрали исключение и слишком поздно задерживаете его, чтобы строки, которые должны были быть выполнены, не выполнялись (например, код для очистки ресурсов или другого кода, который необходимо, чтобы состояние программы было «правильным»), и, как результат, единственная безопасная вещь - закрыть программу.

+0

Это прекрасно, очень лаконично. Одна вещь, мог бы я затем поймать PatternFormatException при всех уловах, ранее написанных выше? Могу ли я поймать отдельные объекты Exception или только общий класс? – AlexLipp

+1

Обычно вы попадаете в 'PatternFormatException' в точке входа в« большую процедуру », которая вызывает этот код и публикуется публично. Если это исключение не предоставляет достаточной информации для внешнего пользователя, чтобы действительно понять, что происходит. Затем вы поймаете его внутренне и повторно выбросите его снова как часть чего-то большего (например, «ParserException»). Не знаете, что вы подразумеваете под «улавливанием отдельных объектов исключения»? Но это похоже на то, что делает «catch». – Domi

3

Если я правильно понимаю ваш вопрос вы можете просто сделать это:

If(somethingBad){ 
    throw new PatternFormatException(); 
} 

Как указано в ответе ниже. Если вы собираетесь снова и снова проверять это исключение, вам может понадобиться метод Static Method/Class (используйте мозг программирования). Например, вы могли бы сделать что-то вроде:

void checkForException(String pattern, String check){ 
    If(!check.equals(pattern)){ 
     throw new PatternFormatException(); 
    } 
} 

Теперь все, что вам нужно сделать, это:

try{ 
    checkForException("abc","123"); 
}catch(PatternFormatException pfe){ 
    System.out.println(pfe); //Whatever you want to happen if the exception is thrown 
} 

Помните, только использовать исключения для исключительных ситуаций ...

ли читаемый над это for more information on exceptions. Я нахожу, что я рядом никогда не использую исключения.

+0

Вы правильно поняли, я думал, что могу это сделать, однако, если у меня есть много похожих строк кода, т. Е. Конструктор, который инициализирует множество переменных, и многие из них производят такую ​​же плохую вещь, это кажется неэффективным. Могу ли я сделать это лучше? – AlexLipp

+0

@AlexLipp Мне нужно будет вернуться к этому чуть позже в качестве служебных звонков, но ... я добавлю к моему вопросу. Ответ от Domi отражает некоторые из того, что я хочу сказать. Прочитайте эту ссылку, которую я разместил, и над тем, что должен был сказать Доми. – buzzsawddog

+1

@AlexLipp Предполагая, что у них есть много похожих строк кода, то все, что может быть инкапсулировано в один метод (что вы должны делать в любом случае), тогда этот метод является тем, который выполняет бросок, а остальные просто передают его стеку –

Смежные вопросы