2009-10-25 63 views
0
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的另一个文件)运行,并在我输入return语句的那一行导致一个StackOverflow错误。我究竟做错了什么?关于退货声明的问题

+1

使用代码按钮。 – 2009-10-25 10:23:18

+0

选择更具可读性的缩进样式(http://en.wikipedia.org/wiki/Indent_style)。另外,请张贴测试代码;你发布的代码没有任何会导致堆栈溢出的东西。为什么歧视1852年以前的几年? – outis 2009-10-25 10:29:01

+1

注意:方法名称以小写字母开头。 – 2009-10-25 10:29:17

回答

0

当然,你需要一个外部if后面的return语句。因为年份可以是<= 1852

如果你的方法应该只处理1852年以后,你可以抛出一个异常。

2

基本上,如果你的方法声明了一个返回值,所以在这个方法中所有的代码路径必须返回的东西,在你发布的代码的情况下,如果什么年< = 1852?在这种情况下返回值应该是多少?

0

提示:如果在isLeapYear()方法的主体中使用return isLeapYear();,则说明它以递归方式调用自身。

提示2:修正代码的缩进问题,让你更容易理解它的错误。

8

编译器是正确的,你的方法的结构意味着它的最后有一个额外的分支路径需要处理,在这种情况下,它是if (year > 1852)的隐形else分支。如果再次调用相同的方法,则实际上只是将它再次引导到同一个分支,因为年份在调用之间不会改变,并且会导致无限递归。

你真的想有就有的答案是什么问题“是任何一年1852之前,闰年?”,但因为这个问题是不实际的原子(阳历二月开始于24 1582)你甚至有一个错误,所以在修复之后,你可以放心地说不,在任何年份之前都不能闰年。

0

当您编写“return IsLeapYear()”时,会导致无限循环。 既然你不在乎1852年之前的年份,只需返回真或假,并获得A -...

0

你必须添加return false;。因为该方法需要返回一个值(布尔值)。 如果你的if中的第一个条件不成立,所有内容都将被跳过。 你的第一个条件检查year<=1852。现在想象一下:如果你的年份是<= 1852,他会返回什么。

1

如果再次调用isLeapYear,它将永远运行。但使用适当的身份。

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

,你可以看到,你没有别的语句,如果(年> 1852),如果(每年100%== 0),因此编译器不能确保返回的值。

1

您需要返回的每个代码路径的值,包括年份早于1853年的值。在您的代码中,不考虑该情况。

以下功能将按照您的意愿工作。我假设你实际上的意思是,因为那是公历开始使用的那年(反正在天主教的世界里)。自从该年10月颁布以来,尽管符合4/100/400规则,但1582年本身并不是闰年。

我已将代码重新格式化为我认为更具可读性的代码 - 我不是return s之后的else s的粉丝,因为它们分解了我的意思(其他人可能不同意,但我相信这一点形式使缩进问题更容易被发现)。而且,最重要的是,你似乎没有考虑到每四年的规则。

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),记录here。由于Java类库提供了一些有用的东西,所以很少需要编写这样一个基本的代码片段(除了作业)。

整个班级,其美(包括改变朱利安 - 格里高利转换日期的能力)记录在here

0

在不改变参数的情况下调用自己的方法,如果进入无限递归的确定方法,请再次调用您的方法,直到堆栈空间不足。

你问关于返回语句,那是你可以改进你的代码和修复递归的地方。

作为一个规则,试图只有一个返回语句。这样做,在这种情况下会导致:

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

顺便说一句我似乎记得,闰年有一些做与4的倍数太:-)

+1

比我的指导原则更少一条规则。特别是如果多返回版本有助于可读性而不牺牲理解所有代码路径的能力 - 使用这样一个小函数,它应该很容易(尽管承认,对于较大的函数来说并非如此)。 – paxdiablo 2009-10-25 13:10:35

+0

你是对的,我的意思是指所有情况都没有好的理由。对于这样的功能,1回报对我来说更具可读性。 – rsp 2009-10-25 13:55:42

0

儒略历的闰年规则,在公历之前被使用,是每四年是一个闰年。 公历日历遵循这一规则,只是为完整的世纪和400年的倍数增加了特殊的规则。

您的代码只计算特殊规则,但遗漏了基本规则(除了缺少返回语句)。