【问题标题】:How to initialize static final variables based on cmd args?如何根据 cmd args 初始化静态最终变量?
【发布时间】:2020-03-01 06:28:59
【问题描述】:

课程简介要求我将可选的 cmd 参数分配给静态最终变量。

我尝试在 main() 中执行此操作,但编译器抱怨“无法为最终变量赋值”。我尝试在 main() 调用的静态方法中执行此操作,但同样的错误。我听说过在其他答案中使用了静态块,但是当我决定分配什么时,我需要能够访问 cmd args。我对参数解析也有些头疼,因为两个参数都应该有默认值,除非提供了一个。非常欢迎任何奖金建议。

public class FibonacciNim {
    private static Scanner myScanner = new Scanner(System.in);
    private static final int NO_OF_HEAPS;
    private static final int TOKENS_PER_HEAP;

    public static void main(String[] args) {
        // set heaps and tokens using args
        if (args.length == 0) {
            NO_OF_HEAPS = 3;
            TOKENS_PER_HEAP = 9;
        } else {
            boolean usageCorrect = false;
            for (int i = 0; i < args.length-1; i++) {
                if (args[i].equals("-heaps")) {
                    try {
                        NO_OF_HEAPS = Integer.parseInt(args[i+1]));
                        usageCorrect = true;
                    } catch (NumberFormatException e) {
                        usageCorrect = false;
                    }
                } else if (args[i].equals("-tokens")) {
                    try {
                        TOKENS_PER_HEAP = Integer.parseInt(args[i+1]);
                        usageCorrect = true;
                    } catch (NumberFormatException e) {
                        usageCorrect = false;
                    }
                }
            }
        }

        ...

    }

    ...

}

感谢阅读!

【问题讨论】:

  • 静态变量真的需要是final的吗?
  • 嘿看起来是个好问题!欢迎!所以 final 可能是 Java 中预先使用的关键字,你也可以尝试在 main 中定义这些变量,因为它们在这里看起来超出了范围。

标签: java static command-line-arguments final


【解决方案1】:

你不能......实际上,真的从命令行将某些东西分配给静态最终变量。 (你也许可以通过非常肮脏的hackery,但这可能不是任务的意图。)

可能的情况是您应该创建一个可变的静态 final 并将其分配给它的内容。这是一种糟糕的做法,你真的不应该在现实生活中这样做,但它至少是合理的。例如,你可以写

static final String[] argHolder = new String[1];
public static void main(String[] args) {
  ...
  argsHolder[0] = args[0];
  ...
}

【讨论】:

  • 我喜欢这个想法,除了我的简介说:“应该可以通过仅更改一个或多个静态变量来更改程序中的令牌堆数量”
  • 在这种情况下,您应该制作非最终的静态变量。
  • 或者可以将它们变成可变的静态最终变量。
  • 意味着输入“一个或多个静态最终变量”。
  • 这……非常奇怪。除了我描述的方式之外,我认为没有其他方法可以实现这一目标。
【解决方案2】:

静态最终变量只能在初始化时赋值。

public class MyClass {

  private static final int NO_OF_HEAPS = 3;

}

非静态最终变量可以在行中或在构造函数中赋值:

public class MyClass {

  private final int NO_OF_HEAPS;

  public MyClass() {
    NO_OF_HEAPS = 9;
  }

}

你可以;但是,通过将静态变量更改为可变项,例如 AtomicInteger

,将它们设置为“基本上”final
public class FibonacciNim {
  private static Scanner myScanner = new Scanner(System.in);
  private static final AtomicInteger NO_OF_HEAPS = new AtomicInteger(0);
  private static final AtomicInteger TOKENS_PER_HEAP = new AtomicInteger(0);

  public static void main(String[] args) {
    // set heaps and tokens using args
    if (args.length == 0) {
        NO_OF_HEAPS.set(3);
        TOKENS_PER_HEAP.set(3);
    }
    ...
  }
}

至于解析命令行参数,您可以查看JCommander http://jcommander.org/

它提供解析命令行参数和填充 POJO 以使用的功能,因此您不必自己解析它们。

【讨论】:

  • 我选择了这个选项,但我的教授的反馈说他认为 AtomicInteger 旨在用于与线程相关的工作。
  • 从技术上讲,他是正确的,这通常是它们的用途,但这并不意味着它们只能用于此目的。如前所述,如果您需要一个静态的最终可变对象,则需要 AtomicInteger 之类的东西,因为 intInteger 是不可变对象。
猜你喜欢
  • 2013-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-03
  • 1970-01-01
相关资源
最近更新 更多