( assez souvent, je me trouve dans des situations ressemblant à ceci: p> in c # vous pouvez le faire comme ceci: p> pour Java, il n'y a pas de bonne substitution, et puisque La proposition d'amélioration de la manipulation des exceptions a été coupée de Java 7 , on dirait que cela prendra au mieux plusieurs années jusqu'à ce que nous obtenions quelque chose comme ça. Ainsi, j'ai décidé de rouler le mien: P> ( Edit: strong> demi-un an plus tard, Rethow final est de retour , ou il semble donc qu'il semble.) p> Utilisation typique: p>
public void doStuff() throws SomeException {
initializeStuff();
try {
doSomeWork();
} catch (Throwable t) {
undoInitialize();
Rethrow.instanceOrUnchecked(SomeException.class, t);
// We shouldn't get past the above line as only unchecked or
// SomeException exceptions are thrown in the try block, but
// we don't want to risk swallowing an error, so:
throw new SomeException("Unexpected exception", t);
}
private void doSomeWork() throws SomeException { ... }
}
3 Réponses :
Si vous êtes censé que votre inaidification se produise, vous voudrez peut-être simplement mettre ce code dans un blocage enfin, comme cela devrait être appelé à un moment donné, vous devriez peut-être toujours nettoyer. P >
Je suis Leery of Attraper Mais, vous n'avez pas montré ce que Vous voudrez peut-être écrire un test de l'unité, essayez différentes classes d'exceptions et voir ce qui fonctionne ou ne fonctionne pas comme prévu, vous pouvez donc documenter le comportement attendu. P> lancé code> comme certaines des exceptions que je veux gérer, et certains je me connectent, comme il n'y a aucune utilité d'exceptions de passage que l'utilisateur ne peut rien faire, comme un
nullpointException code>. p>
someexception code> est défini comme étant défini, mais si un
OutofMemoryException code> est lancé, votre lanceur va attraper, mais ce sera peut-être le même Tapez comme
SOMException code> de sorte que votre wrapper soit nécessaire dans votre fonction d'échantillon, au moins lorsque je regarde la méthode
instanceorunchecked p>
SoméException étend une exception code>. En ce qui concerne la disinitialisation dans
enfin code> - Je veux seulement que l'inaidification se produise si une exception est lancée. Je pouvais bien entendu avoir un drapeau booléen initialement défini sur FALSE, puis la définir comme la dernière chose à la dernière chose dans le bloc code> code>, mais c'est un peu encombrant (et si quelqu'un ajoute du code après sa définition à vrai sans réfléchir à la manipulation d'exception?).
En outre, je l'ai testé, et cela fonctionne très bien ... Dans toutes les circonstances, j'ai pu penser, ce qui ne prouve que si j'ai réussi à écrire du code, je ne suis pas assez intelligent pour me casser =)
Avez-vous été testé avec une classe qui s'étend à DJEBLABLE, et non une exception?
@JB, je n'ai pas. Astucieux! Je devrais probablement changer la contrainte de type sur instanceorunchecked code> à partir d'une exception
sur code> à
s'étend lotable code> pour permettre aux clients de réthorner de telles abominations.
@gustafc - Juste à la recherche de cas que vous ne vous attendez probablement pas. Celui-ci est un problème pour les personnes qui enveloppent leurs appels dans les captures (exceptions) car les erreurs les plus critiques ne sont pas une exception.
@gustafc, au lieu de vérifier un drapeau booléen, essayez de vérifier la référence à l'objet que vous essayiez de créer. Si c'est null, une exception a probablement été attrapée. Et si quelqu'un ajoute du code sans mettre à jour le chèque, ils auront un objet valide ou une nullpoinpointException
Une alternative consiste à avoir une usine qui crée une exception SOMExException uniquement si la cause est une exception vérifiée: La raison pour laquelle je mets dans la valeur de retour dans la méthode est de sorte que le client peut faire quelque chose comme ceci: p> de sorte que le compilateur soit dupe à ne pas nécessiter de retour après la déclaration de capture si la méthode a un type de retour, mais il jette toujours l'exception Si le client a oublié de mettre le lancer avant l'appel à la méthode d'usine. p> L'inconvénient de ce code sur votre code est qu'il est moins portable (cela fonctionne pour la soméexception, mais pas pour une certaine exception), mais cela peut-être bien, car il ne sera pas pour chaque type d'exception que vous devez avoir une initialisation d'annulation. p> S'il correspond à votre cas d'utilisation, vous pouvez mettre l'appel non coché dans le constructeur de SOMException et avoir le logique disponible pour toutes les sous-classes, mais cela devrait correspondre à votre projet spécifique - ce ne serait pas une bonne idée dans le cas général car cela empêcherait d'emballer ru Ntime Exceptions. P> public SomeException(message, cause) {
super(message, unchecked(cause));
}
private static Throwable unchecked(Throwable cause) {
if (cause instanceof Error) throw (Error) cause;
if (cause instanceof RuntimeException) throw (RuntimeException) cause;
return cause;
}
La fonction d'usine est belle, mais depuis que j'ai une hiérarchie d'exception (plusieurs classes s'étendant someexception code>), j'ai besoin de quelque chose de plus flexible. J'aime l'intelligence de la deuxième alternative, mais je pense que c'est peut-être trop intelligent - le potentiel de maintenance du WTF semble élevé.
Il y a un moyen de gérer cela. Le premier est ma préférence si vous n'avez pas besoin de savoir quelle était l'exception.
try { // do some work which might throw an exception } catch (Throwable t) { // do something with t. Thread.currentThread().stop(t); }
Vous avez une bonne justification pour attraper la jante. Ne laissez pas vous descendre. Cela ressemble beaucoup à l'utilisation de goto ", ne l'utilisez jamais, à moins que vous ne l'iez."