#java
#java
Вопрос:
Когда я запускаю код, он возвращает:
31 и -1
Как я могу избавиться от -1? Есть ли способ НЕ возвращать значение в методе INT? Я попытался вернуть java.lang.Целое число (null), но это выдало мне ошибку. Я думаю, что использовал его неправильно.
Вот код:
package com.company;
public class Main {
public static void main(String[] args) {
int y = getDaysInMonth(1, 2020);
System.out.println(y);
}
public static boolean isLeapYear(int year) {
if (year > 1 amp;amp; year < 9999) {
if ((year % 4 == 0 amp;amp; year % 100 != 0) || year % 400 == 0) {
return true;
}
return false;
}
return false;
}
public static int getDaysInMonth(int month, int year) {
if ((month < 1 || month > 12) amp;amp; (year < 1 || year > 9999)) {
return -1;
} else if (!isLeapYear(year)) {
switch (month) {
case 1:
System.out.println(31);
break;
case 2:
System.out.println(28);
break;
case 3:
System.out.println(31);
break;
case 4:
System.out.println(30);
break;
case 5:
System.out.println(31);
break;
case 6:
System.out.println(30);
break;
case 7:
System.out.println(31);
break;
case 8:
System.out.println(31);
break;
case 9:
System.out.println(30);
break;
case 10:
System.out.println(31);
break;
case 11:
System.out.println(30);
break;
case 12:
System.out.println(31);
break;
default:
return -1;
}
} else if (isLeapYear(year)) {
switch (month) {
case 1:
System.out.println(31);
break;
case 2:
System.out.println(29);
break;
case 3:
System.out.println(31);
break;
case 4:
System.out.println(30);
break;
case 5:
System.out.println(31);
break;
case 6:
System.out.println(30);
break;
case 7:
System.out.println(31);
break;
case 8:
System.out.println(31);
break;
case 9:
System.out.println(30);
break;
case 10:
System.out.println(31);
break;
case 11:
System.out.println(30);
break;
case 12:
System.out.println(31);
break;
default:
return -1;
}
} else return -1;
return -1;
}
}
Я перепробовал почти все, должно быть что-то, чего я еще не знаю.
Комментарии:
1. » Когда я запускаю код, он возвращает: 31 и -1 » — Java не поддерживает возврат нескольких значений без объекта-оболочки. Не могли бы вы уточнить, что вы подразумеваете под этим утверждением?
2. Вы можете вернуть значение int только из метода. Использование некоторого невозможного значения, такого как -1, является типичным выбором. Однако в этом случае возвращаемое значение всегда равно -1, так что вы также можете определить метод как void и ничего не возвращать.
3. «Есть ли способ НЕ возвращать значение в методе INT». Нет — нет, если вы хотите, чтобы метод возвращался нормально. (Я бы предположил, что в этом случае он, вероятно, должен выдавать исключение, а не возвращать -1.) Каким бы вы ожидали, что значение
y
будет, если вы не вернули значение изgetDaysInMonth
? Я предлагаю вам выполнить отладку с помощью кода, чтобы выяснить, почему он неожиданно возвращает значение -1. (Подсказка: все вашиcase
операторы выводят значение, но фактически не возвращают …)
Ответ №1:
Это потому, что вы сначала печатаете в методе, а затем снова печатаете возвращаемое значение метода в y .
Вместо того, чтобы печатать каждый раз, попробуйте возвращать значения. Кроме того, программа, которую вы написали, может быть написана намного эффективнее. Вот пример :
public static int getDays(int monthNumber, int yearNumber)
{
if (monthNumber == 2 amp;amp; !isLeapYear(yearNumber))
return 28;
else if (monthNumber==2)
return 29;
else if ((monthNumber >= 1) amp;amp; (monthNumber <= 7) amp;amp; (monthNumber % 2 ==1))
return 31;
else if ((monthNumber >= 8) amp;amp; (monthNumber %2==0))
return 31;
else
return 30;
}
Ответ №2:
Есть ли способ НЕ возвращать значение в методе INT?
Да, конечно. Выдать исключение. Для примера:
if (month < 1 || month > 12) {
throw new IllegalArgumentException("month value is out of range");
}
(Подсказка: я заметил ошибку в вашей существующей проверке ошибок. Внимательно посмотрите на это, когда будете переписывать.)
Выдача исключения приводит к завершению работы метода без возврата какого-либо результата. Даже если в сигнатуре метода указано, что результат должен быть возвращен. Вы можете прочитать об этом в руководствах Oracle Java:https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html . Эта часть руководств по Java объясняет, что такое исключения, как и когда их создавать, как их перехватывать и что происходит, когда вы их не перехватываете.
Сказав это, можно сказать, что есть несколько мест, куда вы возвращаетесь -1
. Вам нужно тщательно проверить каждый из них, чтобы решить, действительно ли это возможно. Если входные данные для getDaysInMonth
действительны, то вы всегда должны иметь возможность вычислить значение «дни в месяце». И вам нужно будет проверить аргументы только в одном месте.
Моя рекомендация заключалась бы в проверке значений аргументов в начале метода. Затем остальная часть метода может быть закодирована в предположении, что аргументы являются допустимыми.
Наконец, если getDaysInMonth
возвращается -1
для getDaysInMonth(1, 2020)
, это указывает на то, что у вас ошибка в логике метода. Я рекомендую вам использовать отладчик, чтобы найти его… если вы не можете определить это, прочитав и логически проанализировав свой код.
Комментарии:
1. ИМХО, это правильный и единственно разумный подход. Хотя это больше кода для предварительной проверки параметров, вместо того, чтобы использовать «менее кодовое» решение no
if
и просто athrow
внизу и позволить переключателю перейти к нему, это легче читать и лучшая практика — кто знает, как код будет вести себя с недопустимыми параметрами.
Ответ №3:
Внимательно посмотрев на вашу функцию, как сейчас, она всегда будет возвращать -1 и ничего больше.
Объявленная функция public static int getDaysInMonth(int month, int year)
должна возвращать int
значение, если она успешно завершается.
Единственный случай, когда он может завершиться без возврата значения, — это выдача исключения.
Итак, я собираюсь предположить, что ваша функция должна возвращать номер дня в месяце, а не просто печатать его.
Вот код для того, что никогда не вернет -1 или любое значение, отличное от 28, 29, 30, 31:
public static int getDaysInMonth(int month, int year) throws IllegalArgumentException {
if (year < 1 || year > 9999) {
throw new IllegalArgumentException(String.format("Invalid year %d must be between 1 and 9999", year));
}
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println(31);
return 31;
case 2:
if (isLeapYear(year)) {
System.out.println(29);
return 29;
} else {
System.out.println(28);
return 28;
}
case 4:
case 6:
case 9:
case 11:
System.out.println(30);
return 30;
}
throw new IllegalArgumentException(String.format("Invalid month %d must be between 1 and 12", month));
}
Обратите внимание на следующие изменения:
-
case
в Java «проваливается», что означает, что вам не нужно писать один и тот же код снова и снова, вы можете помещать случаи с одинаковым результатом один под другим безbrake
инструкции, и все они будут работать вместе, чтобы дать тот же результат. -
В начале функции мы только проверяем, действителен ли год. Если месяц недействителен, ни один из
case
операторов не будет выполнен, и код перейдет непосредственно к строке послеswitch
блока. В этот момент мы знаем, что месяц недействителен, поэтому проверять не нужно, просто удалите исключение. -
Любая функция, которая генерирует исключение, должна объявить, что она делает это в заголовке функции, добавив
throws
предложение и перечислив исключения, разделенные запятыми. -
Когда вы вызываете функцию, которая генерирует исключение, вы должны обернуть его в
try .. catrch
блок.
Ответ №4:
Методы Java могут возвращать только один тип результата:https://www.javatpoint.com/method-in-java
Возвращаемый тип: возвращаемый тип — это тип данных, который возвращает метод. Он может иметь примитивный тип данных, object, collection, void и т.д. Если метод ничего не возвращает, мы используем ключевое слово void.
В качестве обходного пути:
Используйте класс-оболочку
Вы можете использовать Integer
класс в качестве возвращаемого типа и возвращать значение null. Это не намного лучше, чем -1, но это указывает на то, что ничего не было возвращено.
Исключение недопустимого аргумента
Бросьте это:https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html это то, для чего это сделано
default:
throw new IllegalArgumentException("Invalid month value - out of range");
Создать перечисление
Создайте тип enum и используйте его в качестве параметра в своем методе. Таким образом, не будет никакого способа получить неизвестное значение.
public enum Month {
January(1), February(2), March(3), April(4),May(5),June(6), July(7), August(8), September(9), October(10), November(11), December(12)
}