Opa,
Então, entendo que o legal é colocar sentido no código.
Realmente, isso aqui:
catch (Exception e)
resolve porque é a superclasse de exceções mais específicas.
Mas supondo que você queira executar alguma coisa caso um determinado tipo de exceção aconteça, mas o código pode lançar outras exceções que você apenas gravará num log ou algo do tipo.
É possível fazer algo assim:
try{
comando(s);
} catch (FileNotFoundException f) {
comando(s);
} catch (NullPointerException f) {
comando(s);
} catch (Exception e) {
log.error("texto da fora que quiser");
}
Lembrando que isso só funciona quando feito da mais específica para a mais genérica.
Percebe que dá pra colocar lógica dentro do tratamento de exceção?
Falar sobre o mais correto é complicado. O que não pode é deixar de tratar exceções e jogar stacks de erros na cara do usuário ..
Uma coisa legal a se fazer é aplicar conceitos como análise de valor limite e fronteiras nos testes dos programas, pois forçam erros. Isso tende a mostrar exceções não tratadas e deixar a aplicação mais resiliente.