无法为静态 final 变量赋值。

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

Cannot assign value to static final variable

问题

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

  1. import java.io.*;
  2. import java.util.Scanner;
  3. public class Config {
  4. private static final int n = 4;
  5. private static String[] values = new String[n];
  6. public static final String MUSIC_PATH;
  7. public static final String SAVE_PATH;
  8. public static final int WIDTH;
  9. public static final int HEIGHT;
  10. public static void ini() throws FileNotFoundException, IOException {
  11. File f = new File("config.txt");
  12. Scanner lineScanner = new Scanner(f);
  13. for (int i = 0; i < n; i++) {
  14. Scanner valueGetter = new Scanner(lineScanner.nextLine());
  15. valueGetter.useDelimiter(": ");
  16. valueGetter.next();
  17. values[i] = valueGetter.next();
  18. }
  19. WIDTH = Integer.parseInt(values[0]);
  20. HEIGHT = Integer.parseInt(values[1]);
  21. SAVE_PATH = values[2];
  22. MUSIC_PATH = values[3];
  23. }
  24. }

当我尝试编译代码时,我收到“无法为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:

  1. import java.io.*;
  2. import java.util.Scanner;
  3. public class Config {
  4. private static final int n = 4;
  5. private static String[] values = new String[n];
  6. public static final String MUSIC_PATH;
  7. public static final String SAVE_PATH;
  8. public static final int WIDTH;
  9. public static final int HEIGHT;
  10. public static void ini() throws FileNotFoundException, IOException {
  11. File f = new File(&quot;config.txt&quot;);
  12. Scanner lineScanner = new Scanner(f);
  13. for (int i = 0; i&lt;n; i++) {
  14. Scanner valueGetter = new Scanner(lineScanner.nextLine());
  15. valueGetter.useDelimiter(&quot;: &quot;);
  16. valueGetter.next();
  17. values[i] = valueGetter.next();
  18. }
  19. WIDTH = Integer.parseInt(values[0]);
  20. HEIGHT = Integer.parseInt(values[1]);
  21. SAVE_PATH = values[2];
  22. MUSIC_PATH = values[3];
  23. }
  24. }

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方法,并替换为:

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

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

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

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

  1. class Config {
  2. private final int n = 4;
  3. private String[] values = new String[n];
  4. private final String MUSIC_PATH;
  5. private final String SAVE_PATH;
  6. private final int WIDTH;
  7. private final int HEIGHT;
  8. // 获取私有字段的getter方法...
  9. private static Config currentConfig;
  10. public static Config getCurrentConfig() {
  11. return currentConfig;
  12. }
  13. public static void setCurrentConfig(Config currentConfig) {
  14. Config.currentConfig = currentConfig;
  15. }
  16. private Config(File configFile) throws FileNotFoundException {
  17. // 使用configFile的内容初始化final字段...
  18. }
  19. }

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

  1. 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:

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

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

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

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:

  1. class Config {
  2. private final int n = 4;
  3. private String[] values = new String[n];
  4. private final String MUSIC_PATH;
  5. private final String SAVE_PATH;
  6. private final int WIDTH;
  7. private final int HEIGHT;
  8. // getters for the private fields...
  9. private static Config currentConfig;
  10. public static Config getCurrentConfig() {
  11. return currentConfig;
  12. }
  13. public static void setCurrentConfig(Config currentConfig) {
  14. Config.currentConfig = currentConfig;
  15. }
  16. private Config(File configFile) throws FileNotFoundException {
  17. // initialise the final fields using the configFile&#39;s contents...
  18. }
  19. }

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

  1. 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:

确定