Используйте универсального поставщика, чтобы бросить непроверенное исключение - PullRequest
0 голосов
/ 04 января 2019

У меня есть список методов, в котором есть Supplier<T> аргументы для возврата значений по умолчанию различных типов. Однако в некоторых случаях мне нужно выдавать исключение (без проверки) вместо значений.

В настоящее время я должен передавать лямбда-выражение для каждого определения функции, но я хотел бы создать экземпляр поставщика для выдачи исключения и повторно использовать его во всех определениях функций.

У меня есть следующий код:

    public static void main(String[] args)
    {

        testInt("Key1", 10, () -> 99);
        testInt("Key2", -19, () -> 0);
        testInt("Key3", null, () -> {
            throw new UnsupportedOperationException(); //repetition
        });
        testBoolean("Key4", true, () -> Boolean.FALSE);
        testBoolean("Key5", null, () -> {
            throw new UnsupportedOperationException();//repetition
        });
    }

    static void testInt(String key, Integer value, Supplier<Integer> defaultValue)
    {
        if (value != null)
            System.out.printf("Key : %s, Value : %d" + key, value);
        else
            System.out.printf("Key : %s, Value : %d" + key, defaultValue.get());
    }

    static void testBoolean(String key, Boolean value, Supplier<Boolean> defaultValue)
    {
        if (value != null)
            System.out.printf("Key : %s, Value : %d" + key, value);
        else
            System.out.printf("Key : %s, Value : %d" + key, defaultValue.get());
    }

Но я хочу сделать что-то вроде:

final static Supplier<?> NO_VALUE_FOUND = () -> {
        throw new UnsupportedOperationException();
    };


testInt("Key3", null, NO_VALUE_FOUND);
testBoolean("Key5", null,NO_VALUE_FOUND);

Ценю любую помощь по этому вопросу. Спасибо.

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Используйте метод для преобразования значения NO_VALUE_FOUND в соответствующий тип:

static <T>  Supplier<T> NO_VALUE_FOUND() {
    return (Supplier<T>) NO_VALUE_FOUND;
}

public static void main(String[] args) {
    testInt("Key3", null, NO_VALUE_FOUND());
    testBoolean("Key5", null,NO_VALUE_FOUND());
}
0 голосов
/ 04 января 2019

Подобно ответу @ jon-hanson, вы можете определить метод, который возвращает лямбду напрямую, без необходимости приведения:

private <T> Supplier<T> noValueFound() {
    return () -> {
        throw new UnsupportedOperationException();
    };
}
0 голосов
/ 04 января 2019

Лучше было бы использовать более общую реализацию, например:

static <T> void test(String key, T value, Supplier<T> defaultValue) {
    if (value != null)
        System.out.println("Key : " + key + " Value " + value); // note the change from printf since that had type specific placeholders
    else
        System.out.println("Key : " + key + " Value " + defaultValue.get());
}

и далее использовать его как:

public static void main(String[] args) {
    test("Key1", 10, () -> 99);
    test("Key2", -19, () -> 0);
    test("Key3", null, NO_VALUE_FOUND);
    test("Key4", true, () -> Boolean.FALSE);
    test("Key5", null, NO_VALUE_FOUND);
}

с NO_VALUE_FOUND как:

final static Supplier<?> NO_VALUE_FOUND = () -> {
    throw new UnsupportedOperationException();
};

Редактировать (из комментариев): Если вы попытаетесь передать свой NO_VALUE_FOUND типа Supplier<?> в свою тестовую функцию и передать что-либо, кроме литерального значения null в качестве второго аргумента вы получите ошибку компилятора.

Таким образом, для решения тех случаев, когда любое другое значение, кроме нуля, может выдать UnsupportedOperationException, используйте обобщенную реализацию, как , предложенную в ответе MikeFHay.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...