简体   繁体   中英

How do you initialize a datafield inside a loop?

The following code won't compile because the compiler isn't gauranteed that the data field f would be initialized. How do you fix this?

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

Isn't this kind of a glitch in the language because in my other constructor I can have f set to final and just because it's not done in a loop it works. I know the compiler (being dumb) sees a loop and thinks f will be reassigned, but the logic in the program ensures it only happens once. Is this an example of how Java "protects" the programer?

For everyone wondering why f was declared as final Netbeans suggested it, presumably when the code was much different.

private final int f;
        ↑

Remove the final keyword. The compilers doesn't know that the if will be satisfied only once and you'll get an error about trying to change f multiple times:

The final field f may already have been assigned

First of all, final field is field that you can not change value that is assigned to. In your case in each loop move you change that value, so it can not be compile. Remove final word before 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();
                }
    }
}

You .. don't.

I know the compiler (being dumb) sees a loop and thinks f will be reassigned, but the logic in the program ensures it only happens once. Is this an example of how Java "protects" the programmer?

This behavior, whether or not it "protects" the programmer, is a result of how the Java language is defined (per the JLS ) and how the compiler correctly enforces the language specification.

4.12.4. final Variables :

A final variable may only be assigned to once .. It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

See Chapter 16. Definite Assignment which discusses the rules for this limited static analysis case in detail.

private final int f;

You use final for your declaration this will not allow to re-assign another value for f

A final variable can only be initialized once , either via an initializer or an assignment statement.

Read more about final here

so just use

private int f;

当您将任何变量声明为final时,该值的值不应更改。通过这种方式是否需要将变量声明为final?

Here is the catch, you can initialize any final instance on the same place or inside the constructor, but can not initialize inside method( METHOD ).
So you will say that I am initializing inside the constructor!! But the thing is that you are changing final instance variable's value multiple time inside for loop which compiler identifies and throws compiler error.

compiler inline final code like below.

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

ex

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

        Foo() {
            f = 10;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM