Вернуть ноль в методе, который возвращает удваивает Java - PullRequest
1 голос
/ 18 октября 2019

Я пытаюсь проверить наличие нулевого ввода в начале метода. И если найдено значение true, я хочу вернуть значение null, хотя метод обычно возвращает значение типа double.

Мне нужно сохранить тип метода двойным

public double computeMean (double[] grades) {
        if (grades == null) {
            return null;

Невозможно преобразовать ноль в двойное

Ответы [ 2 ]

2 голосов
/ 18 октября 2019

Вы должны использовать

Double класс оболочки (обратите внимание на прописную букву "d")

не double примитивный тип в качестве типа возврата, если выхочу иметь возможность вернуть null.

1 голос
/ 18 октября 2019

Пояснение

null - это значение, которое можно использовать только для объектов. A double однако является примитивом, он не использует объектную систему. Вот почему вы не можете вернуть null, если вы указали double в качестве типа возвращаемого значения.

Итак, каковы ваши варианты?


Double оболочка

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

Поскольку Java обеспечивает автоматическое преобразование между double и Double при необходимости (автобокс), этоможет быть весьма удобным в использовании.

Обратите внимание, что использование Double приводит к небольшим накладным расходам только к небольшому double, и что люди регулярно забывают проверить null при преобразовании Double вdouble. Т.е.

// foo() returns Double
double value = foo(); // Bad code, it could be null!

Вместо этого пользователи должны помнить, чтобы проверить полученное значение:

Double result = foo();
if (result == null) {
    ...
} else {
    double value = result;
    ...
}

OptionalDouble

Современная и, вероятно, лучшая альтернатива,должен использовать Optional (для этого вам нужна как минимум Java 8).

Он был разработан для использования всякий раз, когда метод естественным образом иногда может не возвращать результат. Например, если массив передан в пусто . В этом случае все в порядке и не должно рассматриваться как ошибка.

Это также решает проблему пользователей, которые забывают проверить результат. Optional заставляет их проверять его, иначе они не могут получить базовое значение.

Во избежание снижения производительности Optional<Double> (снова класс оболочки), есть также OptionalDouble, которыйвнутренне использует double (примитив). Вот код:

public OptionalDouble computeMean(double[] grades) {
    if (grades == null) {
        return OptionalDouble.empty();
    }
    ...
    return OptionalDouble.of(result);
}

И использование:

OptionalDouble result = computeMean(...);

Оттуда у пользователя есть несколько вариантов (см., Например, документацию ), например:

double value = result.orElse(10.4);
// or
double value = result.orElseThrow();
// or
if (!result.isPresent()) {
    ...
} else {
    double value = result.getAsDouble();
}

Исключение

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

Я бы сказал, что в вашей конкретной ситуации это так,Невозможно вычислить mean на null. Это отличается от передачи в пустой массив, где я бы пошел для пустого Optional. Для массива null я бы выдал исключение, чтобы указать на неправильное использование.

Хорошим исключением для этой ситуации является IllegalArgumentException, вот код:

public double computeMean(double[] grades) {
    if (grades == null) {
        throw IllegalArgumentException("Grades must not be null!");
    }
    ...
}

Другойидиоматическое исключение именно для этого варианта использования - бросить NullPointerException. Существует даже компактный вспомогательный метод для выполнения всего этого в одной строке:

public double computeMean(double[] grades) {
    Objects.requireNonNull(grades); // Yes, thats it

    ...
}

Результат

Собрав все это вместе, я бы сделал следующие два изменения:

  • Бросок NullPointerException, если grades равен null, используя Objects#requireNonNull
  • Вернуть пустое OptionalDouble, если grades пусто
public OptionalDouble computeMean(double[] grades) {
    Objects.requireNonNull(grades);

    if (grades.length == 0) {
        return OptionalDouble.empty();
    }

    ...
    return OptionalDouble.of(result);
}
...