Вопрос о возврате выписки - PullRequest
       11

Вопрос о возврате выписки

0 голосов
/ 25 октября 2009
import java.util.Scanner;

public class GregorianYear

{
    private int year;

    public GregorianYear(int a)

    {
        year = a;
    }

    public void SetYear()
        {
        System.out.println( "The year is: " );
        Scanner kbd = new Scanner( System.in );
            year = kbd.nextInt();
    }

    public int getYear()
    {
        return year;
    }

    public boolean isLeapYear()
    {
        if ( year > 1852 )
        {
            if ( year % 100 == 0)
            {
                if ( year % 400 == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
    //Compiler says I need a return statement here.
    }
}

Я программирую (должна быть) простую программу для класса, и когда у меня ничего нет, она говорит, что мне нужно выражение return. Я предполагаю, что могу вернуть только логическое выражение, поэтому я ввожу return isLeapYear () ;. Когда я это делаю, мой тестовый метод (другой файл с общедоступной статической void main) запускается и вызывает ошибку StackOverflow в строке, где я ввел оператор return. Что я делаю не так?

Ответы [ 10 ]

8 голосов
/ 25 октября 2009

Компилятор правильный, то, как ваш метод структурирован, означает, что в самом конце есть дополнительный путь ветвления, который необходимо обработать, в этом случае это невидимая ветвь else для if ( year > 1852 ). Если вы снова вызываете тот же метод, вы на самом деле просто перенаправляете его в ту же ветку else, потому что год между вызовами не меняется и это вызывает бесконечную рекурсию.

Что вы действительно хотите получить, так это ответ на вопрос « - это любой год до 1852 года високосный или нет? », однако, поскольку этот вопрос не является атомарным ( григорианский календарь начинается 24 февраля 1582 ) у вас даже есть ошибка, поэтому после исправления вы можете смело сказать, что нет, за все годы до этого не может быть високосных лет.

2 голосов
/ 25 октября 2009

В основном, если ваш метод объявляет возвращаемое значение, поэтому все пути вашего кода в этом методе должны что-то возвращать, в случае кода, который вы разместили, что, если year <= 1852 </strong> ?? какое должно быть возвращаемое значение в этом случае ??

1 голос
/ 25 октября 2009

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

Следующая функция будет работать по вашему желанию. Я предполагаю, что вы на самом деле имеете в виду 1582 , поскольку это был год, когда начал использоваться григорианский календарь (во всяком случае, в католическом мире). Поскольку он был принят в октябре того же года, 1582 год не был високосным, несмотря на соблюдение правил 4/100/400.

Я переформатировал код в соответствии с тем, что я считаю более читабельным стилем - я не большой поклонник return с, за которыми следуют else с, так как они разбивают смысл по моему мнению (другие могут не согласиться, но Я считаю, что эта форма облегчает выявление проблем с отступами). И, кроме того, вы, похоже, вообще не принимаете во внимание правило каждые четыре года.

public boolean isLeapYear() {
    // No leap years before Greg the Pope.

    if ( year < 1583 )
        return false;

    // Multiples of 400 are leap years.

    if ( year % 400 == 0)
        return true;

    // Multiples of 100 (other than multiples of 400) are not.

    if ( year % 100 == 0)
        return false;

    // Multiples of 4 are, assuming they're not multiples of 100.

    if ( year % 4 == 0)
        return true;

    // All other aren't.

    return false;
}

Конечно, идеальным решением, вероятно, является просто использование GregorianCalendar.isLeapYear(int year), задокументированное здесь . Очень редко вам приходится писать такой базовый кусок кода (кроме домашних заданий), поскольку библиотеки классов Java предоставляют огромный массив полезных вещей.

Весь класс во всей его красоте (включая возможность изменить юлиан-григорианскую дату перехода) задокументирован здесь .

1 голос
/ 25 октября 2009

Если вы снова вызовете isLeapYear, он будет работать вечно. Но используйте правильную идентификацию.

if ( year > 1852 )
{
   if ( year % 100 == 0)
   {
      if ( year % 400 == 0)
      {
         return false;
      }
      else
      {
         return true;
      }
   }
}

Как видите, у вас нет оператора else для if (year> 1852) и if (year% 100 == 0), поэтому компилятор не может быть уверен, что значение возвращено.

0 голосов
/ 25 октября 2009

Правило високосного года юлианского календаря, которое использовалось до григорианского календаря, заключается в том, что каждый четвертый год является високосным. Григорианский календарь сохраняет это правило и просто добавляет исключительные правила для полных веков и кратных 400 лет.

Ваш код вычисляет только исключительные правила, но пропускает основное правило (кроме пропущенных операторов возврата).

0 голосов
/ 25 октября 2009

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

Вы спрашиваете о операторах возврата, и именно здесь вы можете улучшить свой код и исправить рекурсию.

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

public boolean isLeapYear()
{
    boolean result = false;
    if ( year > 1852 )
    {
            if ( year % 100 == 0)
            {
                    if ( year % 400 != 0)
                    {
                            result = true;
                    }
            }
    }
    return result;
}

Кстати, я помню, что високосные годы также имеют отношение к коэффициентам 4: -)

0 голосов
/ 25 октября 2009

Вы должны добавить return false;. Потому что метод должен возвращать значение (логическое). И если ваше первое условие в вашем if не соответствует действительности, все будет пропущено. Ваше первое условие проверяет year<=1852. А теперь представьте: что он вернет, если ваш год будет <= 1852.

0 голосов
/ 25 октября 2009

Когда вы пишете «return IsLeapYear ()», вы вызываете цикл infinte.Поскольку вас не волнуют годы до 1852 года, просто верните true или false и получите A -...

0 голосов
/ 25 октября 2009

Подсказка: если вы используете return isLeapYear(); в теле метода isLeapYear(), вы говорите ему рекурсивно вызывать себя.

Подсказка 2: исправьте отступ в вашем коде, и вам будет легче понять, что с ним не так.

0 голосов
/ 25 октября 2009

Конечно, вам нужно выражение return после внешнего if. Потому что год может быть <= 1852.

Если ваш метод должен обрабатывать только годы после 1852 года, вы можете выдать исключение.

...