无法为静态 final 变量赋值。

huangapple go评论78阅读模式
英文:

Cannot assign value to static final variable

问题

我正在尝试为我的游戏创建一个配置文件系统,我希望用户提供的配置信息被存储为Config类中的public static final变量,以便游戏中的所有类都可以安全地访问配置数据。以下是我迄今为止编写的代码:

import java.io.*;
import java.util.Scanner;

public class Config {

    private static final int n = 4;
    private static String[] values = new String[n];
    public static final String MUSIC_PATH;
    public static final String SAVE_PATH;
    public static final int WIDTH;
    public static final int HEIGHT;

    public static void ini() throws FileNotFoundException, IOException  {
        File f = new File("config.txt");
        Scanner lineScanner = new Scanner(f);
        for (int i = 0; i < n; i++) {
            Scanner valueGetter = new Scanner(lineScanner.nextLine());
            valueGetter.useDelimiter(": ");
            valueGetter.next();
            values[i] = valueGetter.next();
        }
        WIDTH = Integer.parseInt(values[0]);
        HEIGHT = Integer.parseInt(values[1]);
        SAVE_PATH = values[2];
        MUSIC_PATH = values[3];
    }
}

当我尝试编译代码时,我收到“无法为final变量分配值”的错误消息。如果我删除了final关键字,代码可以正常工作,但我宁愿不这样做,因为它们是公共变量,我不希望它们被误操作。

我认为在我目前的方法中,没有轻松的方法来解决这个问题,但如果有人可以查看这个问题并告诉我如何实现我想要的目标,我将不胜感激 无法为静态 final 变量赋值。

英文:

I am trying to create a config file system for my game, and I want the config info from the user to be stored as public static final variables in a Config class, so all classes within the game can access the config data safely. Here is the code I have written so far:

import java.io.*;
import java.util.Scanner;

public class Config {

	private static final int n = 4;
	private static String[] values = new String[n];
	public static final String MUSIC_PATH;
	public static final String SAVE_PATH;
	public static final int WIDTH;
	public static final int HEIGHT;

	public static void ini() throws FileNotFoundException, IOException  {
		File f = new File(&quot;config.txt&quot;);
		Scanner lineScanner = new Scanner(f);
		for (int i = 0; i&lt;n; i++) {
			Scanner valueGetter = new Scanner(lineScanner.nextLine());
			valueGetter.useDelimiter(&quot;: &quot;);
			valueGetter.next();
			values[i] = valueGetter.next();
		}
		WIDTH = Integer.parseInt(values[0]);
		HEIGHT = Integer.parseInt(values[1]);
		SAVE_PATH = values[2];
		MUSIC_PATH = values[3];

	}

}

When I try to compile the code I get the error "cannot assign a value to final variable". I am able to get the code working if I remove the final, however I would prefer not to do this as they are public variables I don't want them getting messed up or anything.

I figure there is no easy way to get around this issue with the way I have currently done it, but if anyone can look at this and tell me a way to accomplish what I want then I would appreciate 无法为静态 final 变量赋值。

答案1

得分: 2

您可以在静态块中初始化static final字段。

因此,请删除ini方法,并替换为:

static {
   // 曾经在ini方法中的代码在这里...
}

请注意,静态块无法抛出已检查异常,因此在创建Scanner时需要处理异常:

try {
    Scanner lineScanner = new Scanner(f);
    // 其余的代码...
} catch (FileNotFoundException e) {
    // 在这里处理异常...
    // 可能将字段设置为某些默认值
}

我还建议将字段设置为私有,并为它们添加getter方法。此外,考虑根本不将它们设置为static,而是使用公共setter设置静态currentConfig字段。它看起来可能像这样:

class Config {

    private final int n = 4;
    private String[] values = new String[n];
    private final String MUSIC_PATH;
    private final String SAVE_PATH;
    private final int WIDTH;
    private final int HEIGHT;

    // 获取私有字段的getter方法...

    private static Config currentConfig;

    public static Config getCurrentConfig() {
        return currentConfig;
    }

    public static void setCurrentConfig(Config currentConfig) {
        Config.currentConfig = currentConfig;
    }

    private Config(File configFile) throws FileNotFoundException {
        // 使用configFile的内容初始化final字段...
    }
}

在程序开始时,您可以这样做:

Config.setCurrentConfig(new Config(new File("config.txt")));
英文:

You can initialise static final fields in a static block.

So remove the ini method, and replace it with:

static {
   // the code that used to be in the ini method here...
}

Note that a static block cannot throw checked exceptions, so you need to handle the exception when creating a Scanner:

try {
    Scanner lineScanner = new Scanner(f);
    // the rest of your code...
} catch (FileNotFoundException e) {
    // handle the exception here...
    // perhaps set the fields to something default
}

I would also recommend making the fields private add getters for them. Also consider not having them static at all, and instead have a static currentConfig field that can be set with a public setter. It would look something like this:

class Config {

    private final int n = 4;
    private String[] values = new String[n];
    private final String MUSIC_PATH;
    private final String SAVE_PATH;
    private final int WIDTH;
    private final int HEIGHT;

    // getters for the private fields...

    private static Config currentConfig;

    public static Config getCurrentConfig() {
        return currentConfig;
    }

    public static void setCurrentConfig(Config currentConfig) {
        Config.currentConfig = currentConfig;
    }

    private Config(File configFile) throws FileNotFoundException {
        // initialise the final fields using the configFile&#39;s contents...
    }
}

At the start of your program you'd then do something like this:

Config.setCurrentConfig(new Config(new File(&quot;config.txt&quot;)));

huangapple
  • 本文由 发表于 2023年6月13日 15:43:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76462687.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定