Raccourci pour la logique "If / Throw, Else/ Return" dans Java 8?

Est-il une syntaxe plus courte si/jeter else/retour en Java 8? java.util.Optional fournit un moyen d'accomplir cela dans une instruction, mais il nécessite de créer une instance Optional avec chaque appel qui a une référence non nulle.

Cela peut-il être accompli en une seule déclaration?

public static MyEnum fromString(String value) {
    MyEnum result = enumMap.get(value);
    if (result == null)
        throw new IllegalArgumentException("Unsupported value: " + value);
    return result;
}

Exemple facultatif (mauvais, nécessite une instance facultative à chaque fois)

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(
        () -> new IllegalArgumentException("Unsupported value: " + value));
}
26
demandé sur Sam Berry 2014-10-22 07:32:48

2 réponses

L'impact d'une instance Optional temporaire est négligeable. Habituellement, la JVM détecte sa nature temporaire et optimise l'instance. Même si la création d'instance temporaire n'est pas optimisée, l'impact d'un seul objet temporaire sur la gestion de la mémoire est ridiculement faible.

Cependant, si la carte est mutable, vous pouvez utiliser l'astuce suivante:

public static MyEnum fromString(String value) {
    return enumMap.computeIfAbsent(value, v -> {
        throw new IllegalArgumentException("Unsupported value: " + v); });
}

Notez que le Map n'est pas modifié par ce code mais doit toujours être mutable car une carte immuable peut lancer un UnsupportedOperation exception pour la tentative d'utilisation de computeIfAbsent sans jamais vérifier si l'opération modifierait réellement la carte.


Mais à la fin, il n'y a rien de mal avec Optional. Mais notez que le code dans votre question est faux. L'expression lambda que vous passez à la méthode Optional.orElseThrow est destinée à approvisionnement le d'exception, de ne pas jeter:

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(() ->
        new IllegalArgumentException("Unsupported value: " + value) // just return it
    );
}
27
répondu Holger 2014-10-22 08:58:12

Si vous êtes prêt à vivre avec NullPointerException, vous pouvez faire:

public static MyEnum fromString(String value) {
    return requireNonNull(enumMap.get(value), () -> "Unsupported: " + value);
}

Cela suppose import static java.util.Objects.requireNonNull

Modifier:

Si vous êtes vraiment particulier sur le type d'exception que vous lancez, implémentez simplement votre propre méthode utilitaire statique:

static<T, X extends Throwable> T nonNullOrThrow(T val, Supplier<? extends X> exSupplier) throws X {
    if (val != null) return val;
    else throw exSupplier.get();
}

Alors vous serez en mesure de faire

return nonNullOrThrow(enumMap.get(value), () -> new IllegalArgumentException("unsupported: " + k));
3
répondu Misha 2014-10-22 05:22:13