Как правильно выйти из метода (имеющего возвращаемый тип ‘int’), фактически не возвращая вообще никакого значения в Java?

#java #return-value

#java #возвращаемое значение

Вопрос:

Ниже приведен код, с которым я столкнулся при реализации стека с использованием LinkedList. Кодирование может показаться неправильным и неразборчивым. Однако вопрос находится за пределами темы, и фрагмент предоставляет только контекст.

 1.   public int pop() {
2.       int x;
3.       if (len==0){
4.           System.out.println("Already empty.");
5.           return;    //Says this method must return a result of type int?
6.       }
7.  
8.       int x = myLinkedList.deleteFromBegin();//this function returns the deleted integer
9.       --len;
10.      return x;
11.  }
  

В приведенном выше коде отсутствует формальный способ выхода из метода. Оператор return в строке 5 не хочет возвращать значение при специальном условии. Но обычно функция должна возвращать значение int, показывающее только что выскочившее число.

Комментарии:

1. вы либо возвращаете (со значением), либо выбрасываете Throwable .

2. Вы также можете вернуть Optional<Integer> , но в этом случае исключение тоже кажется уместным (в конце концов, это то, что делает стек Java ). Я бы не стал предлагать возвращать какое-то «волшебное» значение, поскольку все они также могут быть элементами в списке.

3. @SudhirOjha ужасная идея. Как можно отличить значение сигнала от фактического 0 или -1 , которое было сохранено в списке?

Ответ №1:

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

Быстрый сбой

 throw new RuntimeException("Empty list"); 
  

Если вы обнаружите, что вы не можете открыть, потому что список пуст, вы создаете исключение. Таким образом, вы можете сохранить тип int для подписи вашего метода. Следствием этого является то, что перед вызовом pop вы должны быть уверены, что список не пуст и может предоставить функцию типа isEmpty() или length(), чтобы вызывающий мог проверить на своей стороне. Вы в основном считаете, что вызов pop в пустом списке является ошибкой.

Возвращает специальное значение, если список пуст.

 return -1;
  

Это опасно, и его следует избегать. Теперь ваша реализация зависит от того, что это значение не используется для другого значения. если вы используете -1, например, но клиентский код хочет законно добавить число -1 в этот список, вы не сможете отличить пустой список от элемента заголовка, который имеет значение -1.

Оберните тип, чтобы правильно представить эту концепцию.

 return null;
// or
return Optional.empty();
  

Либо используйте тип объекта для целых чисел (Integer), либо используйте «null» в качестве специального значения. Или используйте необязательный и связанный метод isPresent() этого типа.

Пожалуйста, обратите внимание, что усилия так же высоки для вызывающего. Он должен проверить наличие null или isPresent() .

Заключение

Лично я предпочитаю случай исключения, поскольку не имеет смысла выводить пустой список, и я хочу, чтобы он не работал должным образом. Он также быстро завершается с ошибкой, и журнал дает мне точный контекст, в котором произошел сбой. Значение null / optional или значение int по умолчанию зависит от клиента, выполняющего правильную обработку журналов / исключений, и они могут забыть это сделать.

Комментарии:

1. Это отличное объяснение здесь для -1 и null, спасибо.

Ответ №2:

Для этого существует определенное исключение: https://docs.oracle.com/javase/10/docs/api/java/util/EmptyStackException.html это https://docs.oracle.com/javase/10/docs/api/java/util/Stack.html#pop () использование.

Таким образом, вы можете «return» без int . Во всех остальных случаях вам необходимо указать значение int, которое может быть содержимым стека, чтобы вы не знали, является ли это пустым стеком или фактическим содержимым, если вы всегда не проверяете длину перед появлением.

Если вам разрешено изменять подпись, вы можете изменить возвращаемый тип на Optional<Integer> и return Optional.empty() и Optional.of(x) для других случаев.

Ответ №3:

Если ваш возвращаемый тип находится int там, где вы пишете return , вы также должны возвращать допустимое целочисленное значение.

Подход 1: создать исключение:

Есть еще один вариант выхода из метода без возврата — выдать исключение JavaDoc:

 3.       if (len==0){
4.           System.out.println("Already empty.");
5.           throw new Exception("Already empty");  // or new RuntimeException(). or any other exception.
6.       }
  

Подход 2: возвращать необязательно

Если вы хотите разделить регистр при возврате int или ничего, вы можете изменить возвращаемый тип с int на Optional<Integer> JavaDoc

 1.   public Optional<Integer> pop() {
2.       int x;
3.       if (len==0){
4.           System.out.println("Already empty.");
5.           return Optional.empty();    //Says this method must return a result of type int?
6.       }
7.  
8.       int x = myLinkedList.deleteFromBegin();//this function returns the deleted integer
9.       --len;
10.      return Optional.of(x);
11.  }
  

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

 Optional<Integer> x = pop();
if (x.isPresent()){
    x.get() // process returned value.
}
  

Комментарии:

1. Существует также OptionalInt специально для этого варианта использования.