9
votes

Comment regrouper enfin catch en une seule méthode en java 8?

Nouveau sur java 8, j'aimerais optimiser mon code ci-dessous:

} catch (Exception e) {
    codeA;
} finally {
    codeB;
}

J'ai beaucoup de méthodes utilisant cette même manière pour attraper les exceptions et faire la même chose enfin, est-ce possible remplacer le code commun ci-dessous par une méthode en java 8? Pour que je puisse optimiser toutes mes méthodes qui utilisent ce code commun.

public Response create() {
    try{
        ...
    } catch (Exception e) {
        codeA;
    } finally {
        codeB;
    }
}

public Response update() {
    try{
        ...
    } catch (Exception e) {
        codeA;
    } finally {
        codeB;
    }
}


4 commentaires

Il se peut que ce soit un cas pour AutoCloseable et try-with-resources . Par exemple, si finalement vous appelez close () sur quelque chose. JDBC bénéficie d'essayer avec des ressources, mais également de ses propres classes implémentant Autocloseable. Ensuite, il n'y a pas besoin d'une pièce finale.


Il existe certaines options pour atteindre la réutilisabilité dans votre code, cependant, cela nécessitera une refactorisation et d'autres stratégies OO. Similaire à Joop dit. - le codeB peut-il être refactorisé? peut utiliser l'interface AutoCloseable? si c'est le cas, vous pouvez extraire le code nécessaire pour le fermer dans une classe séparée et utiliser l'initialisation ou la référence d'objet avec des instructions try-with-resource, supprimant ainsi le besoin de bloc finally. - le codeA que vous pouvez refactoriser pour utiliser une implémentation d'exception personnalisée - Une autre alternative est l'utilisation de la programmation orientée aspect (AOP) pour injecter le code nécessaire à la gestion des exceptions.


Voulez-vous vraiment attraper et agir sur les exceptions générales dans vos méthodes create () et update () au lieu de les laisser se répercuter sur leurs appelants respectifs et ainsi de suite? Signification: Comment allez-vous informer votre appelant que la création / mise à jour n'a pas réussi?


L'inversion de contrôle (avec lambdas ou interfaces) est ce que vous recherchez. Cela peut être avec des frameworks (intercepteurs) ou en utilisant des bibliothèques comme Spring JDBC Template. MAIS je pense que c'est souvent un signe d'avertissement si vous en avez besoin et le code n'est pas toujours plus facile à suivre et à maintenir.


3 Réponses :


15
votes

Dépend de ce que vous faites dans le ... . Vous pouvez faire quelque chose comme ceci:

public Response create() { return method(() -> { ... for create }); }
public Response update() { return method(() -> { ... for update }); }

et appeler comme:

private Response method(Supplier<Response> supplier) {
    try{
        return supplier.get();
    } catch (Exception e) {
        codeA;
    } finally {
        codeB;
    }
}


2 commentaires

8
votes

Vous pouvez encapsuler votre payload et la placer dans la méthode séparée. Une chose; que vous attendez-vous à retourner sur exception catch. Cette fois, c'est null , mais vous pourriez probablement fournir une valeur par défaut.

public Response create() {
    return execute(() -> new CreateResponse());
}

public Response update() {
    return execute(() -> new UpdateResponse());
}

Le code client pourrait ressembler à ceci:

public static <T> T execute(Supplier<T> payload) {
    try {
        return payload.get();
    } catch(Exception e) {
        // code A
        return null;
    } finally {
        // code B
    }
}


0 commentaires

0
votes

Cela pourrait être une solution générique.

//here describe supplier which can throw exceptions

@FunctionalInterface
public interface ThrowingSupplier<T> {
    T get() throws Exception;
}

// The wrapper
private <T> T callMethod(ThrowingSupplier<T> supplier) {
    try {
        return supplier.get();
    } catch (Exception e) {
        //code A
    }finally {
        // code B
    }
}


0 commentaires