Подтвердить что ты не робот

Сокращение для логики "If/Throw, Else/Return" в Java 8?

Есть ли более короткий синтаксис для if/throw else/return в Java 8? java.util.Optional предоставляет средство для достижения этого в одном утверждении, но для этого требуется создать экземпляр Optional с каждым вызовом, который имеет ненулевую ссылку.

Может ли это быть выполнено в одном выражении?

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

Необязательный пример (плохо, требуется дополнительный экземпляр каждый раз)

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(
        () -> new IllegalArgumentException("Unsupported value: " + value));
}
4b9b3361

Ответ 1

Влияние временного экземпляра Optional незначительно. Обычно JVM будет определять свой временный характер и оптимизировать экземпляр. Даже если создание временного экземпляра не оптимизировано, воздействие одного временного объекта на управление памятью смехотворно низкое.

Однако, если карта изменчива, вы можете использовать следующий трюк:

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

Обратите внимание, что Map не изменяется этим кодом, но все же должен быть изменен, поскольку неизменяемая карта может вызывать исключение UnsupportedOperation для попытки использовать computeIfAbsent, не проверяя, действительно ли операция действительно изменит карту.


Но в конце нет ничего плохого в Optional. Но учтите, что код в вашем вопросе неверен. Выражение лямбда, которое вы передаете методу Optional.orElseThrow, предназначено для предоставления желаемого исключения, а не для его броска:

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(() ->
        new IllegalArgumentException("Unsupported value: " + value) // just return it
    );
}

Ответ 2

Если вы готовы жить с NullPointerException, вы можете сделать:

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

Это предполагает import static java.util.Objects.requireNonNull

Edit:

Если вы действительно относитесь к тому, какой тип исключения вы бросаете, просто используйте свой собственный статический метод утилиты:

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

Затем вы сможете сделать

return nonNullOrThrow(enumMap.get(value), () -> new IllegalArgumentException("unsupported: " + k));