L'extension de Throwable en Java

Java vous permet de créer un tout nouveau sous-type de Throwable, e.g:

public class FlyingPig extends Throwable { ... }

Maintenant, très rarement, je peut faire quelque chose comme ceci:

throw new FlyingPig("Oink!");

et bien sûr ailleurs:

try { ... } catch (FlyingPig porky) { ... }

Mes questions sont:

  • Est-ce une mauvaise idée? Et si oui, pourquoi?
    • Ce qui aurait pu être fait pour l'empêcher de sous-typage si c'est une mauvaise idée?
    • Puisqu'il n'est pas évitable (autant que je sache), ce catastrophes pourrait entraîner?
  • Si ce n'est pas une mauvaise idée, pourquoi pas?
    • Comment pouvez-vous faire quelque chose d'utile du fait que vous pouvez extends Throwable?

Proposé scénario #1

Un scénario où j'ai été vraiment tenté de faire quelque chose comme ce qui a les propriétés suivantes:

  • "L'événement" est quelque chose qui sera arriver par la suite. Il est devrait. Le plus n'est certainement pas un Error, et il n'y a rien Exception-al quand il se produit.
    • Parce que c'est devrait, il y aura un catch en attente pour elle. Il ne sera pas "glisser" dans le passé, rien. Il ne sera pas "s'échapper" de toute tentative de catch général Exception et/ou Error.
  • "L'événement" qui se passe extrêmement rarement.
  • Lorsque cela se produit, habituellement, il y a une profonde trace de la pile.

Alors peut-être il est clair maintenant que je suis en train de dire: FlyingPig est le résultat d'une minutieuse recherche récursive.

L'objet à rechercher existe: c'est seulement une question de le trouver dans la grande mer, qui est l'espace de recherche. Le processus de recherche sera longue, de sorte que le coût relativement élevé de la gestion des exceptions est négligeable. En fait, le traditionnel contrôle de flux de construire une autre de l'utilisation d'un boolean isFound drapeau peut être plus cher, car il faut contrôler en permanence tout au long du processus de recherche, le plus souvent, à chaque niveau de la récursivité. Cette vérification échoue à 99,99% du temps, mais c'est absolument nécessaire pour propager la résiliation condition. Dans un sens, tandis que efficace, la vérification est inefficace!

Simplement throw-ing un FlyingPig lorsque l'cherché objet est trouvé, vous n'avez pas à encombrer le code avec la gestion de la boolean isFound drapeau. Non seulement le code plus propre à cet égard, mais il peut courir plus vite en raison de cette omission.

Donc, pour résumer, le choix est entre ces deux:

  • Traditionnelles de contrôle des flux de
    • Utiliser un boolean isFound, contrôler en permanence
    • 99,99% du temps, la vérification est un "déchet", car il faudrait toujours être false
    • Quand il devient finalement true, vous vous arrêtez recursing et vous devez vous assurer que vous pouvez bien vous détendre à l'appel initial.
  • FlyingPig approche
    • Ne vous embêtez pas avec tout boolean isFound.
    • Si trouvé, juste throw new FlyingPig(); c'est devrait, alors il y aura une catch pour elle.
    • Pas de gestion de boolean drapeau, pas de gaspillage de vérifier si vous avez besoin de continuer, pas de tenue de livres manuelle de se détendre la récursivité, etc.

Questions:

  • Est cette technique de (ab)à l'aide d'exception est-elle valide? (Est-il un nom pour ça?)
  • Si elle est valable, doit FlyingPig extends Throwable, ou est Exception bien? (même si il n'y a rien d'exceptionnel à ses circonstances?)
  • Drôle d'idée, je suis juste à penser, si cela peut être utilisé pour laisser de la JVM de synchroniser les threads. Est attraper throwables asynchrone?
  • J'ai utilisé une fois un class Finished extends Exception pour exactement la même raison: la Performance de sortir d'une longue recherche récursive. Mais je n'ai jamais justifié cette raison que le fait de mesurer la performance.
  • Enfin!!! Quelqu'un qui a eu la même idée que j'ai fait! Je devrais probablement prendre une étape supplémentaire et de référence. Sera probablement un jour.