61 votes

LBYL vs l'aeap en Java?

J'ai été récemment l'enseignement de moi-même Python et découvert le LBYL/l'aeap les expressions idiomatiques. En Python, il semble acceptée dans le style est l'aeap, et il semble bien fonctionner avec la langue.

Pour ceux qui ne connaissent pas, LBYL et de l'aeap reportez-vous à Regarder Avant de Sauter et Il est plus Facile de Demander Pardon Que la Permission, à la fois en ce qui concerne la vérification des erreurs avant l'exécution de code.

LBYL:

def safe_divide_1(x, y):
    if y == 0:
        print "Divide-by-0 attempt detected"
        return None
    else:
        return x/y

L'aeap:

def safe_divide_2(x, y):
    try:
        return x/y
    except ZeroDivisionError:  
        print "Divide-by-0 attempt detected"
        return None

Ma question est: est-ce que je n'avais jamais entendu parler de l'utilisation de l'aeap que les données primaires de validation de construire, en provenance de Java et de C++ arrière-plan. Est l'aeap quelque chose qui est sage d'utiliser en Java? Ou est-il trop généraux des exceptions? Je sais qu'il y a seulement les frais généraux lorsqu'une exception est générée, donc je suis pas sûr pourquoi, la méthode la plus simple de l'aeap n'est pas utilisé. Est-ce juste une préférence?

124voto

Jonathan Leffler Points 299946

Si vous accédez à des fichiers, l'aeap est plus fiable que LBYL, parce que les opérations impliquées dans la LBYL ne sont pas atomiques, et le système de fichiers peut changer entre le moment où vous regardez et le temps de faire le grand saut. En fait, le nom standard est TOCTOU Temps de Vérifier, au Moment de l'Utilisation; bugs causés par l'inexactitude de la vérification sont TOCTOU bugs.

Envisager la création d'un fichier temporaire qui doit avoir un nom unique. Le meilleur moyen pour savoir si le nom de fichier choisi existe encore est d'essayer de créer elle - assurez-vous d'utiliser les options pour s'assurer que votre opération échoue si le fichier existe déjà (dans POSIX/Unix termes, la O_EXCL drapeau d' open()). Si vous essayez de tester si le fichier existe déjà (probablement à l'aide de access()), puis entre le moment où il dit "Non" et le temps que vous essayez de créer le fichier, quelqu'un ou quelque chose d'autre peut avoir créé le fichier.

Inversement, supposons que vous essayez de lire un fichier existant. Votre vérifier que le fichier existe (LBYL): "il est là", mais lorsque vous l'ouvrez, vous trouverez "il n'est pas là".

Dans ces deux cas, vous avez pour vérifier la dernière opération - et la LBYL n'a pas automatiquement de l'aide.

(Si vous êtes de jouer avec SUID ou SGID programmes de, access() pose une autre question; il peut être pertinent de LBYL, mais le code a encore de prendre en compte la possibilité d'un échec.)

47voto

Jeff Shannon Points 3439

En plus du coût relatif des exceptions en Python et Java, gardez à l'esprit qu'il y a une différence de philosophie et d'attitude entre eux. Java essaie d'être très strict sur les types (et tout le reste), nécessitant explicite, des déclarations détaillées de classe/méthode de signatures. Il suppose que vous devez connaître, à tout moment, de quel type d'objet que vous utilisez et ce qu'il est capable de faire. En revanche, Python "duck typing" signifie que vous ne sais pas pour vous (et ne devrait pas soins) ce qui le manifeste type d'un objet, vous avez seulement besoin de soins qu'il charlatans quand vous le demandez. Dans ce genre d'environnement permissif, la seule saine d'esprit, l'attitude est à présumer que les choses vont travailler, mais être prêt à faire face aux conséquences si elles ne le font pas. Java est naturel de restriction ne rentre pas bien avec une telle désinvolture. (Ce n'est pas prévu pour dénigrer soit l'approche ou de la langue, mais plutôt de dire que ces attitudes sont une partie de chaque langue, du langage et de la copie des idiomes entre les différentes langues peuvent souvent conduire à de la maladresse et de la mauvaise communication...)

11voto

mipadi Points 135410

Les Exceptions sont gérées plus efficacement en Python qu'en Java, ce qui est au moins en partie pourquoi vous voyez que construire en Python. En Java, la plus inefficace (en termes de performances) utiliser les exceptions de cette façon.

9voto

Yuval Adam Points 59423

Personnellement, et je pense que ceci est soutenu par convention, l'aeap n'est jamais une bonne façon d'aller. Vous pouvez le regarder comme un équivalent au suivant:

if (o != null)
    o.doSomething();
else
    // handle

par opposition à:

try {
    o.doSomething()
}
catch (NullPointerException npe) { 
    // handle
}

En outre, considérez les points suivants:

if (a != null)
    if (b != null)
        if (c != null)
            a.getB().getC().doSomething();
        else
            // handle c null
    else
        // handle b null
else
    // handle a null

Cela peut paraître beaucoup moins élégant (et oui c'est un exemple brut - ours avec moi), mais il vous donne beaucoup plus de granularité dans la gestion de l'erreur, par opposition à l'enveloppant le tout dans un try-catch pour obtenir que l' NullPointerException, puis essayer de comprendre où et pourquoi vous l'avez obtenu.

La façon dont je vois l'aeap ne doit jamais être utilisé, sauf en de rares situations. Aussi, puisque vous avez soulevé la question: oui, le bloc try-catch n'engager des frais généraux , même si l'exception n'est levée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X