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错误。我做错了什么?
答案 0 :(得分:8)
编译器是正确的,你的方法结构的方式意味着在它的最末端有一个额外的分支路径需要处理,在这种情况下它是{{1}的不可见else
分支}}。如果你再次调用相同的方法,你实际上只是将它指向同一个else分支,因为年份不会在调用之间发生变化,从而导致无限递归。
你真正希望得到的答案是“是否是1852年之前的任何一年闰年?”,但是因为这个问题实际上并不是原子的( Gregorian日历从2月24日开始 1582 )你甚至在那里有一个错误,因此在确定之后你可以安全地说不,在此之前的任何年份都不能闰年。
答案 1 :(得分:2)
基本上,如果你的方法声明了一个返回值,那么这个方法中的所有代码路径都必须返回一些内容,如果是你发布的代码,那么如果 year< = 1852 ?在这种情况下应该返回什么值?
答案 2 :(得分:1)
如果再次调用isLeapYear,它将永远运行。但要使用正确的身份。
if ( year > 1852 )
{
if ( year % 100 == 0)
{
if ( year % 400 == 0)
{
return false;
}
else
{
return true;
}
}
}
如你所见,你没有if(year> 1852)和if(year%100 == 0)的else语句,因此编译器无法确定是否返回了值。
答案 3 :(得分:1)
您需要返回每个代码路径的值,包括年份早于1853年的值。在您的代码中,不考虑该情况。
以下功能可以按您的意愿使用。我假设你实际上意味着 1582 ,因为那是公历开始使用的年份(无论如何,在天主教世界)。自从那年10月颁布以来,尽管符合4/100/400规则,1582本身并不是闰年。
我已经将代码重新格式化为我认为更具可读性的风格 - 我不是return
s的忠实粉丝,其次是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)
,记录here。你很少需要编写这样一个基本的代码片段(除了作业),因为Java类库提供了一个有用的巨大的数组。
整个班级,其所有的美丽(包括改变朱利安 - 格里高利安切换日期的能力)都记录在案here。
答案 4 :(得分:0)
当然你需要在外部if后面的return语句。因为年份可以是<= 1852
。
如果你的方法只能在1852年之后处理几年,你可以抛出异常。
答案 5 :(得分:0)
提示:如果您在return isLeapYear();
方法的正文中使用isLeapYear()
,则告诉它以递归方式调用自身。
提示2:修复代码的缩进,让您更容易理解它的错误。
答案 6 :(得分:0)
当您编写“return IsLeapYear()”时,会导致无限循环。 由于你不关心1852年之前的年份,只需返回true或false并获得A -...
答案 7 :(得分:0)
您必须添加return false;
。因为该方法需要返回一个值(布尔值)。
如果你的if中的第一个条件不成立,那么一切都将被跳过。
您的第一个条件检查year<=1852
。现在想象一下:如果你的年份是<= 1852
,他将会回归什么。
答案 8 :(得分:0)
调用自己的方法而不更改参数,如果有可能进入无限递归,再次调用方法直到堆栈用完空间。
您询问返回语句,这是您可以改进代码并修复递归的地方。
通常尝试只有一个return语句。在这种情况下执行此操作将导致:
public boolean isLeapYear()
{
boolean result = false;
if ( year > 1852 )
{
if ( year % 100 == 0)
{
if ( year % 400 != 0)
{
result = true;
}
}
}
return result;
}
顺便说一下,我似乎记得闰年也与4的倍数有关: - )
答案 9 :(得分:0)
在公历之前使用的朱利安历法的闰年规则是每四年都是闰年。 公历遵循这一规则,只是为整个世纪和400年的倍数增加了特殊的规则。
您的代码仅计算例外规则,但错过了基本规则(除了缺少的返回语句)。