简体   繁体   中英

Final variable may already have been assigned

I am writing a program that has two final variables that I wish to use, I need these to be set at the time that I actually run the class because they are likely to be different each instance.

I have the initialization the same as any other class variable I wish to use where I initialize a name and type but not a value.

   public final String filename, filepath;

In the Constructor I set the values as follows

 public myClass(String value) {
     this.filename = value;
     this.filepath = anotherPartOfValue;
  }

When I do this, I get a warning that "The final field [x] may have already been assigned"

Is there a way to avoid this warning and still keep the final state and set the value in the constructor?

I am using eclipse btw.


Edit:

This is the exact code that gives me the error

import java.io.*;

public class Dirt {

private String[] tables;
private int numTables;
private final String filename, filepath;

public Dirt(String file) {
    this.tables = new String[0];
    this.numTables = 0;

    for (int i = file.length(); i < 0; i--) {
        if (file.charAt(i) == '/') {
            this.filename = file.substring(i);
            this.filepath = file.substring(1, i-1);
        }
    }
}

}

The problem is that you are assigning to the final variables in a loop. There's nothing to prevent the loop from looping more than once and the if condition being satisfied more than once. (What happens if there are two '/' characters in file ? Or none?)

One way around this is to use temporary String variables in the constructor and then assign them to filename and filepath at the end:

public Dirt(String file) {
    this.tables = new String[0];
    this.numTables = 0;
    String name = null;
    String path = null;

    for (int i = file.length(); i < 0; i--) {
        if (file.charAt(i) == '/') {
            name = file.substring(i);
            path = file.substring(1, i-1);
            // need a break here?
        }
    }
    this.filename = name;
    this.filepath = path;
}

It's ugly, but it's a straightforward way to know for sure that filename and filepath will definitely be assigned and definitely be assigned only once.

Completely compileable and runnable:

public static void main(String[] args) {
    Foo f = new Foo("abc");
    System.out.println(f.filename);
    System.out.println(f.filepath);
}

static class Foo {
    public final String filename, filepath;
    public Foo(String value) {
        this.filename = value;
        this.filepath = value.substring(1);
    }
}

And the "warning" you mention isn't just a warning. It's an error. But it's not coming from here.

Edit: Your newly posted code has the assignments in a loop. By definition, statements in a loop can execute multiple times, and therefore you have the potential for assigning the final variables multiple times.

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