2014-09-03 87 views
3

我有上編譯這段代碼用javac麻煩:「變量可能尚未初始化」即使我確定它是

public static int getYear() { 
    Console input = System.console(); 
    Boolean gotYear = false; 
    int year; 

    String userInput = input.readLine(); 

    while (!gotYear) { 
     try { 
      year = Integer.parseInt(userInput); 
      gotYear = true; 
     } catch (Exception e) { 
      System.out.print("Please insert a valid date. "); 
      userInput = input.readLine(); 
     } 
    } 

    return year; 
} 

javac的給我上線return year;的錯誤「變量「年「可能尚未初始化」。但是因爲它是在一個while循環中的,所以我知道它會被初始化。我問我的T.A.對此,他無法回答我爲什麼會發生這種情況。他最好的猜測是Javac並不是一個很好的編譯器,可以用來計算這種東西。

基本上,這個錯誤爲什麼會發生?我知道我可以通過在進入while循環之前初始化一年來解決它,但我想知道是否有另一種方法來實現我想要實現的目標。

+1

只是初始化一年'-1' – EpicPandaForce 2014-09-03 14:18:44

+0

有了,你現在有,在「年份」變量尚未初始化,可能無法初始化代碼。如果你的while循環不執行會怎麼樣?只需使用默認值,如-1。 – Marko 2014-09-03 14:21:06

+0

不要爲程序流使用catch塊。 – Stefan 2014-09-03 14:21:18

回答

6

你的年份變量是在try塊中初始化的。對我們來說很明顯,在輸入OK之前,它不會退出循環。但編譯器的規則比這更簡單:由於初始化可能會被異常中斷,因此認爲該年可能未初始化。

+0

我希望它沒有雖然拋出一個錯誤。如果它是一個警告,我能夠理解,但一個錯誤讓我覺得很不好我的代碼:( – raphaelgontijolopes 2014-09-03 20:28:42

+0

作爲@Zhuinden建議在評論中,初始化一年默認值當你聲明它與編譯器將不再產生錯誤。 – Julien 2014-09-04 07:26:21

2

不需要。您必須初始化。本地aka方法變量在使用之前必須被初始化。

本地變量不會得到默認值。在使用之前,你必須初始化它們。

0

您必須初始化局部變量。通過This瞭解基本知識

0

局部變量主要用於中間計算,而實例變量應該帶有未來和中間計算的數據。 對於實例變量,Java允許默認值,但對於本地變量,Java允許分配值。所以爲了避免錯誤,你需要初始化局部變量。

1

試想一個情況,當 gotYear

while (!gotYear) 

評估爲真正

在這種情況下,將不會被初始化,因爲它在while循環中。

while (!gotYear) { 
    try { 
     year = Integer.parseInt(userInput); 
     gotYear = true; 
    } catch (Exception e) { 
     System.out.print("Please insert a valid date. "); 
     userInput = input.readLine(); 
    } 
} 

在編譯時,java編譯器不計算表達式。因此得到了可以採取兩個值之一 true false

局部變量應該在聲明它們的相同範圍內進行初始化。初始化應該在使用之前完成。

0

year將不會被分配給Integer.parseInt(userInput);拋出一個NumberFormatException。

gotYear然後保持爲Boolean.FALSE保留在循環中,對於編譯器來說太複雜了。它認爲你可能會以某種方式退出循環。

以下應該表現得更好。

for (;;) { 
    try { 
     year = Integer.parseInt(userInput); 
     break; 
    } catch (Exception e) { 
     System.out.print("Please insert a valid date. "); 
     userInput = input.readLine(); 
    } 
} 

也許只是編譯器可能接受:

for (boolean keepAsking = true; keepAsking;) { 
    try { 
     year = Integer.parseInt(userInput); 
     keepAsking = false; 

BTW更好,而不是對象包裝類Boolean使用boolean

+0

著名的和這麼難看空「爲(;;)」,並提醒我們的基本。 – Julien 2014-09-03 14:32:28

+0

的「破發」請問爲什麼使用的'布爾'優選(而不是'Boolean')? – raphaelgontijolopes 2014-09-03 14:40:33

+0

布爾是基本類型(如int),其中包含的假真布爾是一個子類對象的,並持有一個布爾值,它因此可以爲空了。 – 2014-09-03 14:51:59