2014-01-22 51 views
1

下面的代碼不會編譯,因爲編譯器不能保證數據字段f將被初始化。你如何解決這個問題?如何初始化循環內的數據字段?

import java.util.Scanner;

public class Foo 
{ 
    private final int f; 
    /*constructor*/ 
    public Foo() 
    { 
     Scanner sc = new Scanner(System.in); 
     for(int i = 0; i < 10; i++) 
       { 
        if(i == 5) 
         f = sc.nextInt();//error: variable f might be assigned in a loop 
       } 
    } 

    public Foo(int i) 
    { 
      j = i;//no problem 
    } 
} 

是不是這種在語言毛刺的,因爲我在其他的構造,我可以有f設置爲final,只是因爲它不是在一個循環中完成它的工作原理。我知道編譯器(愚蠢)看到一個循環,並認爲f將被重新分配,但程序中的邏輯確保它只發生一次。這是Java如何「保護」程序員的例子嗎?

對於大家想知道爲什麼f被聲明爲final的Netbeans提出的建議,想必當代碼是非常不同的。

+1

爲什麼爲f決賽?當你每隔一次迭代並賦值時 – Hrishikesh

+0

放下「最後」? – Fildor

+0

原因是因爲f是最終的。 – Hrishikesh

回答

2
private final int f; 
     ↑ 

刪除final關鍵字。編譯器不知道if會滿意只有一次,你會得到關於設法改變f多次錯誤:

最終場F可能已經被分配

+0

@ user2864740謝謝,你是對的,我把它刪除了。 – Maroun

+0

哦,我喜歡這個答案,只是挑剔。 – user2864740

1

首先,final字段是您無法更改分配給的值的字段。在你每次循環移動的情況下,你改變這個值,所以它不能被編譯。在f之前刪除最後的單詞。

public class Foo 
{ 
    private int f; 
    /*constructor*/ 
    public Foo() 
    { 
     Scanner sc = new Scanner(System.in); 
     for(int i = 0; i < 10; i++) 
       { 
        if(i == 5) 
         f = sc.nextInt(); 
       } 
    } 
} 
+0

現在f不是最終的:D見上面。 – RMachnik

+0

請提前致謝! – RMachnik

0
private final int f; 

你用最後的你的宣言,這將不允許重新分配另一個值對於f

最後一個變量只能使用一次初始化,無論是通過 初始化或者一個賦值語句。

瞭解更多關於最終here

因此就使用

private int f; 
0

當U聲明任何變量作爲最終,該值的價值不應該changed.By的方式有任何需要宣佈你的變量爲最終?

1

你..不。

我知道編譯器(愚蠢)看到一個循環,並認爲f將被重新分配,但程序中的邏輯確保它只發生一次。這是Java如何「保護」程序員的例子嗎?

這種行爲,無論是否「保護」的程序員,是Java語言是如何(每JLS),以及如何編譯器能夠正確強制執行語言規範定義的結果。

4.12.4. final Variables

甲最終變量可以僅被分配給一次.. 它是一個編譯時間錯誤,如果最後的變量分配給除非它是絕對未分配(§16)之前立即到任務。

參見Chapter 16. Definite Assignment其中討論用於詳細此有限靜態分析的情況下的規則。

0

這裏是catch,你可以在同一個地方或構造函數內初始化任何final實例,但不能初始化方法(METHOD)。
所以你會說我正在初始化構造函數!但問題是你正在多次修改final實例變量的值,以便編譯器識別並返回編譯器錯誤。

編譯內聯最終代碼,如下所示。

private final int f = 10 //even if you initialize it inside the constructor only one time. 

public class Foo { 
     private final int f; // byte code becomes 'private final int f = 10' for each instance 

     Foo() { 
      f = 10; 
     } 
    }