如何根据 cmd args 初始化静态最终变量?
How to initialize static final variables based on cmd args?
课程作业要求我将可选的 cmd 参数分配给静态最终变量。
我曾尝试在 main() 中执行此操作,但编译器抱怨 "cannot assign a value to final variable"。我试过用 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 并将其分配给其中的内容。这是一种糟糕的做法,在现实生活中你真的不应该这样做,但它至少是合理的。例如,您可以写
static final String[] argHolder = new String[1];
public static void main(String[] args) {
...
argsHolder[0] = args[0];
...
}
静态最终变量只能在初始化时赋值。
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
,将它们设置为 "essentially" 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 的功能,因此您不必自己解析它们。
课程作业要求我将可选的 cmd 参数分配给静态最终变量。
我曾尝试在 main() 中执行此操作,但编译器抱怨 "cannot assign a value to final variable"。我试过用 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 并将其分配给其中的内容。这是一种糟糕的做法,在现实生活中你真的不应该这样做,但它至少是合理的。例如,您可以写
static final String[] argHolder = new String[1];
public static void main(String[] args) {
...
argsHolder[0] = args[0];
...
}
静态最终变量只能在初始化时赋值。
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
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 的功能,因此您不必自己解析它们。