Yep, comme les autres l'ont dit, un try
bloc inhibe certaines optimisations à travers l' {}
personnages qui l'entourent. En particulier, l'optimiseur doit supposer qu'une exception peut se produire à n'importe quel point à l'intérieur du bloc, donc il n'y a aucune assurance que les instructions sont exécutées.
Par exemple:
try {
int x = a + b * c * d;
other stuff;
}
catch (something) {
....
}
int y = a + b * c * d;
use y somehow;
Sans l' try
, la valeur calculée à attribuer à l' x
a pu être sauvé comme un "sous-expression" et réutilisés pour attribuer à l' y
. Mais à cause de l' try
il n'y a aucune assurance que la première expression n'a jamais été évalué, de sorte que l'expression doit être recalculé. Ce n'est généralement pas un gros problème en "ligne droite" de code, mais peuvent être importants dans une boucle.
Il convient de noter, toutefois, que cela ne s'applique qu'à JITCed code. javac ne fait qu'un minable montant de l'optimisation, et il y a un coût nul pour l'interpréteur de bytecode pour entrer/quitter un try
bloc. (Il n'y a pas bytecode généré pour marquer les limites des blocs.)
Et pour bestsss:
public class TryFinally {
public static void main(String[] argv) throws Throwable {
try {
throw new Throwable();
}
finally {
System.out.println("Finally!");
}
}
}
Sortie:
C:\JavaTools>java TryFinally
Finally!
Exception in thread "main" java.lang.Throwable
at TryFinally.main(TryFinally.java:4)
javap de sortie:
C:\JavaTools>javap -c TryFinally.class
Compiled from "TryFinally.java"
public class TryFinally {
public TryFinally();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
()V
4: return
public static void main(java.lang.String[]) throws java.lang.Throwable;
Code:
0: new #2 // class java/lang/Throwable
3: dup
4: invokespecial #3 // Method java/lang/Throwable."<init
>":()V
7: athrow
8: astore_1
9: getstatic #4 // Field java/lang/System.out:Ljava/
io/PrintStream;
12: ldc #5 // String Finally!
14: invokevirtual #6 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
17: aload_1
18: athrow
Exception table:
from to target type
0 9 8 any
}
Pas de "GOTO".
0 votes
Pour autant que je sache, un bloc try est très bon marché en Java.
32 votes
Cette question n'a vraiment aucun sens. Essayez catch a un but très précis. Si vous en avez besoin, vous en avez besoin. De toute façon, à quoi sert un try sans un catch ?
1 votes
Est-il possible d'avoir un try sans catch à moins d'utiliser un finally dans le bloc ?
54 votes
try { /* do stuff */ } finally { /* make sure to release resources */ }
est légal et utile4 votes
Ce coût doit être mis en balance avec les avantages. Il ne se suffit pas à lui-même. Dans tous les cas, ce qui est cher est relatif, et jusqu'à ce que vous sachiez que vous ne pouvez pas le faire, il est logique d'utiliser la méthode la plus évidente plutôt que de ne pas faire quelque chose parce que cela pourrait vous faire gagner une milliseconde ou deux au cours d'une heure d'exécution du programme.
1 votes
La question liée discute du fait que c'est pas le site
try
qui est "coûteux" mais qui traite l'exception et déroule la pile. Si vous avez besoin de traiter les exceptions, vous devez traiter les exceptions0 votes
@A4L Je ne savais même pas que c'était possible, intéressant.
0 votes
@user2246674 Parfois, vous ouvrez des ressources dans une méthode que vous voulez absolument fermer, même si la méthode lève une exception à un moment donné. Le bloc finally est garanti de s'exécuter.
4 votes
J'espère que cela ne mène pas à une situation du type "réinventons les codes d'erreur"...
6 votes
@SAFX : avec Java7, vous pouvez même vous débarrasser de l'option
finally
en utilisant untry-with-resources
3 votes
Cette réponse : stackoverflow.com/a/10978562/330315 affirme que le bloc d'essai lui-même n'a pas de coût du tout.
2 votes
@JohnFx J'ai interprété la question comme étant à propos de try-catch : "... utiliser un bloc try catch ...", mais avec le bloc catch très rarement, voire jamais, exécuté. Cette question pourrait avoir une incidence sur le coût de la déclaration d'une méthode pour lancer une exception vérifiée.
3 votes
JohnFx Il y a un point à cette question. Si
try
était coûteuse, vous pourriez alors proposer une méthode alternative sur une classe qui renvoie un résultat au lieu de lever une exception. Par exemple, en C# :int.Parse()
vsint.TryParse(...)
.1 votes
@JohnFx Pas un try sans catch, mais un try-catch avec une exception qui se déclenche rarement.
1 votes
Je ne comprends pas comment cette question a en quelques jours 48 upvotes et sa réponse aussi, et 2K+ vues ? Une sorte de campagne de publicité ? Comme le dit le commentaire le plus populaire, c'est inutile ! Si l'exception doit être gérée, la capture doit être là ; avec quoi allez-vous comparer le "coût" ? avec un crash ?
2 votes
@quinestor ce commentaire est faux, s'il vous plaît lisez la suite, je demandais, si nous avons un bloc try-catch, mais l'exception ne se produit jamais (ou rarement), est-ce que cela nuit à la performance du code à l'intérieur du try...
1 votes
@Jesse, cette question porte sur java, et celle-ci stackoverflow.com/questions/1308432/ est à propos de C#
0 votes
@JohnFx 'never occurs' = n'est pas lancé, alors le bloc try-catch ne devrait pas être là. rarement" "nuit aux performances" ? quelle est la comparaison des performances ? par rapport au fait de ne pas gérer une exception et d'avoir un crash ?
0 votes
@anakata Vous avez raison. Cela m'a complètement échappé. C'est mon erreur.
1 votes
@JohnFx
try-finally
(ou, avec ARM en Java, simplementtry
) abondent dans le bon code. Vous n'avez certainement pas besoin decatch
pour être utile, et la plupart des problèmes liés aux exceptions proviennent d'une mauvaise gestion des exceptions.catch
blocs.