Nous avons déjà vu à plusieurs reprises au fil des exemples que certaines méthodes, ou certaines actions pouvaient éventuellement générer des erreurs, ou des exceptions. La génération d’un objet "exception" est la façon par laquelle la machine Java nous signale qu’une action s’est mal déroulée, qu’un fichier n’a pas pu être ouvert, qu’une division par zéro a eu lieu, ou qu’une lecture a été tentée au-delà de la limite d'un tableau. Une exception caractérise le déroulement non nominal d'un programme ; elle peut être prévue (cas de l'impossibilité d'ouvrir un fichier), ou imprévisible, comme l'impossibilité de poursuivre l'exécution d'un programme du fait d'un manque de mémoire.
Il existe deux types d’exception en Java : celles pour lesquelles il est nécessaire de prévoir une action appropriée, et les autres. Par exemple, il n’est pas besoin, à chaque fois que l’on fait une opération sur un tableau, de prévoir le cas où le programme va tenter de lire des valeurs au-delà de la limite de ce tableau. De même, il n'est pas nécessaire de prévoir le cas d'une division par zéro à chaque fois que l'on divise deux entiers. C'est d'ailleurs assez heureux ! En revanche, il est nécessaire de prévoir le cas où l'ouverture d'un fichier ne pourra pas se faire. Cette séparation des exceptions en deux catégories est indispensable. On parlera de
checked exception
pour une exception que l'on doit gérer et de
unchecked exception
pour une exception que l'on n'a pas besoin de gérer.
Il y a deux façons de réagir au déclenchement d'une exception pour un programme. Soit l'exception est traitée localement au code exécuté, soit l'exception est transmise à la fonction appelante, qui elle-même peut choisir ce qu'elle en fait.
Enfin, si l'API standard de Java propose un jeu d’exceptions préétabli, il est parfaitement possible d’en définir d’autres, utilisables dans son propre programme.