2009-10-25 97 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年的倍數增加了特殊的規則。

您的代碼只計算特殊規則,但遺漏了基本規則(除了缺少返回語句)。