如何在循环内初始化数据字段?

时间:2014-01-22 07:59:39

标签: java oop

以下代码将无法编译,因为编译器无法保证数据字段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被宣布为最终的Netbeans建议它,大概是当代码有很大不同时。

6 个答案:

答案 0 :(得分:2)

private final int f;
        ↑

删除final关键字。编译器不知道if只会满足一次,并且您会在尝试多次更改f时遇到错误:

  

可能已经指定了最终字段f

答案 1 :(得分: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();
                }
    }
}

答案 2 :(得分:1)

你......不。

  

我知道编译器(是哑的)看到一个循环并认为f将被重新分配,但程序中的逻辑确保它只发生一次。这是Java如何“保护”程序员的一个例子吗?

这种行为,无论是否“保护”程序员,都是Java语言定义的结果(根据JLS)以及编译器如何正确执行语言规范。

4.12.4. final Variables

  

最终变量只能分配给一次.. 如果分配了最终变量,那么这是一个编译时错误,除非在分配之前它是明确未分配的(§16)。

请参阅Chapter 16. Definite Assignment,其中详细讨论了此有限静态分析案例的规则。

答案 3 :(得分:0)

private final int f;

您使用final作为声明,这将不允许为f

重新分配另一个值
  

最终变量只能通过一个初始化一次   初始化程序或赋值语句。

详细了解最终here

所以只需使用

private int f;

答案 4 :(得分:0)

当你将任何变量声明为final时,不应该更改该值的值。那么是否需要将变量声明为final?

答案 5 :(得分:0)

这是catch,你可以在同一个地方或构造函数内部初始化任何最终实例,但不能初始化内部方法(METHOD)。
所以你会说我在构造函数中初始化!!但问题是你在for循环中多次更改最终实例变量的值,编译器会识别并抛出编译器错误。

编译内联最终代码,如下所示。

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;
        }
    }