Ces instructions de code sont-elles équivalentes? Y a-t-il une différence entre eux?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Oui, il y a une énorme différence - le dernier avalera l'exception (le montrant, certes), alors que le premier le laissera se propager. (Je suppose que showException
ne le rediffuse pas.)
Donc, si vous appelez la première méthode et que "faire quelque chose" échoue, l'appelant devra gérer l'exception. Si vous appelez la deuxième méthode et que "faire quelque chose" échoue, l'appelant ne verra aucune exception ... ce qui est généralement une mauvaise chose, sauf si showException
a véritablement manipulé l'exception, corrigé tout ce qui n'allait pas, et généralement vérifié que calculateArea
avait atteint son objectif.
Vous pourrez le savoir, car vous ne pouvez pas appeler la première méthode sans soit attraper Exception
vous-même o déclarant que votre méthode pourrait la lancer aussi.
Premier throws Exception
, l'appelant doit donc gérer le Exception
. La seconde attrape et gère Exception
en interne, de sorte que l'appelant n'a pas à gérer les exceptions.
Oui. La version qui déclare throws Exception
aura besoin du code appelant pour gérer l'exception, alors que la version qui le gère explicitement ne le fera pas.
c'est-à-dire simplement:
performCalculation();
vs déplacer le fardeau de gérer l'exception à l'appelant:
try {
performCalculation();
catch (Exception e) {
// handle exception
}
Oui, il y a beaucoup de différence entre eux. Dans le premier bloc de code, vous passez l'exception au code appelant. Dans le deuxième bloc de code, vous le gérez vous-même. Quelle méthode est correcte dépend entièrement de ce que vous faites. Dans certains cas, vous voulez que votre code gère l'exception (si un fichier n'est pas trouvé et que vous voulez le créer, par exemple), mais dans d'autres, vous voulez que le code appelant gère l'exception (un fichier n'est pas trouvé et ils doivent en spécifier un nouveau ou en créer un).
De manière générale, vous ne voulez pas intercepter une exception générique. Au lieu de cela, vous ne voudrez attraper que des objets spécifiques, tels que FileNotFoundException
ou IOException
car ils peuvent signifier différentes choses.
Il y a un scénario particulier où nous ne pouvons pas utiliser de lancers, nous devons utiliser try-catch. Il existe une règle "Une méthode surchargée ne peut pas générer d'exception supplémentaire autre que celle que la classe parente lève". S'il y a une exception supplémentaire qui devrait être gérée à l'aide de try-catch. Considérez cet extrait de code. Il y a une classe de base simple
package trycatchvsthrows;
public class Base {
public void show()
{
System.out.println("hello from base");
}
}
et sa classe dérivée:
package trycatchvsthrows;
public class Derived extends Base {
@Override
public void show() {
// TODO Auto-generated method stub
super.show();
Thread thread= new Thread();
thread.start();
try {
thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// thread.sleep(10);
// here we can not use public void show() throws InterruptedException
// not allowed
}
}
Lorsque nous devons appeler thread.sleep (), nous sommes obligés d'utiliser try-catch, ici nous ne pouvons pas utiliser:
public void show() throws InterruptedException
parce que la méthode surchargée ne peut pas lancer d’exceptions supplémentaires.
Si vous avez levé une exception, la méthode enfant (qui la remplace) devrait gérer l’exception.
exemple:
class A{
public void myMethod() throws Exception{
//do something
}
}
A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
Je suppose que par "identique" vous faites référence au comportement.
Un comportement d'une fonction peut être déterminé par:
1) valeur retournée
2) exceptions levées
3) Effets secondaires (changements dans le tas, le système de fichiers, etc.)
Dans ce cas, la première méthode propage une exception, tandis que la seconde ne lève aucune exception vérifiée et engloutit également la plupart des exceptions non vérifiées. Le comportement IS est différent.
Cependant, si vous garantissez que "faire quelque chose" ne lève jamais une exception, le comportement serait alors identique (bien que le compilateur demande à l'appelant de gérer l'exception, dans la première version)
--modifier--
Du point de vue de la conception des API, les méthodes sont complètement différentes dans leur contrat. De plus, lancer une classe d'exception n'est pas recommandé. Essayez de lancer quelque chose de plus spécifique pour permettre à l'appelant de mieux gérer l'exception.
L'appelant de cette méthode devra soit intercepter cette exception, soit la déclarer comme étant à nouveau modifiée dans sa signature de méthode.
private void calculateArea() throws Exception {
// Do something
}
Dans l'exemple du bloc try-catch ci-dessous. L'appelant de cette méthode n'a pas à s'inquiéter de la gestion de l'exception car elle a déjà été prise en charge.
private void calculateArea() {
try {
// Do something
} catch (Exception e) {
showException(e);
}
}
Plusieurs fois, vous voulez que l'appelant gère l'exception. Supposons que l'appelant appelle une méthode qui appelle une autre méthode qui appelle une autre méthode. Au lieu de laisser chaque méthode gérer l'exception, vous pouvez simplement la gérer chez l'appelant. À moins que vous ne vouliez faire quelque chose dans l'une des méthodes lorsque cette méthode échouait.
private void calculateArea() throws Exception {
....do something
}
Ceci lève l'exception, donc l'appelant est responsable de la gestion de cette exception, mais si l'appelant ne gère pas l'exception, il se peut que cela soit attribué à jvm, ce qui peut entraîner une interruption anormale du programme.
Attendu que dans le second cas:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Ici, l'exception est gérée par l'appelé, il n'y a donc aucune chance de terminer le programme de façon anormale.
Try-catch est l'approche recommandée.
OMI,
Le mot clé Throws est généralement utilisé avec les exceptions Checked pour convaincre le compilateur, mais ne garantit pas la fin normale du programme.
Lance le mot clé déléguant la responsabilité de la gestion des exceptions à
l’appelant (JVM ou une autre méthode).
Le mot clé Throws est requis uniquement pour les exceptions vérifiées. Pour les exceptions non vérifiées, le mot clé Throws n'est pas utilisé.